我正在使用HibernateTemplate3 + Spring,我发现自己需要按日期列出ProfilingReport对象,按平均时间分组。 问题是显然Hibernate无法将我的选择映射到我的模型中的ProfilingReport对象。 我想知道是否有办法做到这一点,因为它只是返回一个目标数组列表。
这是我的ProfilingReport类的开始(减去getter和setter):
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类:
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;
}
}
这是我试图在我的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);
}
答案 0 :(得分:0)
尝试这个hql更改,
@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);
}
然后你需要通过java业务逻辑本身找到runTime的平均值。
否则,使用现有的数组对象列表,您可以迭代并创建ProfilingReport对象,并将这些数组值分配给ProfilingReport中的相关属性。最后将每个ProfilingReport对象添加到列表(List)中。
答案 1 :(得分:0)
解决方法是使用Hibernate org.hibernate.annotations.Formula注释:
@Entity
@Table(name = "ProfilingReport")
public class ProfilingReport extends Persistent {
private String serviceName;
private long runTime;
@Temporal(javax.persistence.TemporalType.DATE)
private Date date;
@org.hibernate.annotations.Formula("select AVG(p.runTime) from Profiling p group by p.serviceName") private Number averageRunTime;
然后按日期运行查询:
@Override
@Transactional(readOnly = true)
public List<ProfilingReport> getProfilingReports(final Date fecha) {
String query = "from ProfilingReport p "
+ "where p.date = :fecha ";
return this.hibernateTemplate.findByNamedParam(query, "fecha", fecha);
}
另一种解决方案是使用SQL窗口函数,如果您的数据库支持它们(Oracle,PostgreSQL),那么您只需要一个本机查询,窗口函数允许您在嵌入聚合结果时保留所选行,就像您想要的那样首先。