Question

Im using HibernateTemplate3 + Spring, and I find myself needing a list of ProfilingReport objects by date, grouping by their average times. The problem is that apparently Hibernate can not map my selection to the ProfilingReport object from my model. Id like to know if there is a way to do this, since it is just returning a list of arrays of objects at the moment.

This is the beggining of my ProfilingReport class (minus getters and setters):

import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Temporal;

@Entity
@Table(name = "ProfilingReport")
public class ProfilingReport extends Persistent {

private String serviceName;
private long runTime;
@Temporal(javax.persistence.TemporalType.DATE)
private Date date;

My Persistent class from which all persistent classes extend:

import java.io.Serializable;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;

@MappedSuperclass
public class Persistent implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Version
private Long version;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public long getVersion() {
    return version;
}

public void setVersion(Long version) {
    this.version = version;
}
}

And this is the method im trying to execute in my DAO:

@Override
@Transactional(readOnly = true)
public List<ProfilingReport> getProfilingReports(final Date fecha) {
    String query = "select  p.id, p.version, p.serviceName, AVG(p.runTime), date "
            + "from Profiling p "
            + "where p.date = :fecha "
            + "group by p.serviceName";

    return this.hibernateTemplate.findByNamedParam(query, "fecha", fecha);
}

No correct solution

OTHER TIPS

Try this hql changes,

@Override
@Transactional(readOnly = true)
public List<ProfilingReport> getProfilingReports(final Date fecha) {
String query = "from ProfilingReport p "
        + "where p.date = :fecha "
        + "group by p.serviceName";

return this.hibernateTemplate.findByNamedParam(query, "fecha", fecha);
}

Then you need to find average of runTime by java business logic itself.

Otherwise with your existing list of array object you can iterate and create ProfilingReport object and assign these array values to relevant properties in ProfilingReport. Finally add each ProfilingReport object into a list(List).

On solution would be to use Hibernate org.hibernate.annotations.Formula annotation:

@Entity
@Table(name = "ProfilingReport")
public class ProfilingReport extends Persistent {

    private String serviceName;
    
    private long runTime;
    
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date date;
    
    @Formula(
        "select AVG(p.runTime) from Profiling p group by p.serviceName"
    ) 
    private Number averageRunTime;
    
}

And then just run your query by date:

@Override
@Transactional(readOnly = true)
public List<ProfilingReport> getProfilingReports(final Date fecha) {
    return this.hibernateTemplate.findByNamedParam(
        "from ProfilingReport p where p.date = :fecha", 
        "fecha", 
        fecha
    );
}

Another solution is to use SQL window functions if your database supports them, then you just need a native query and the window function allows you to retain the selected rows while embedding the aggregate result, just like you wanted in the first place.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top