Hibernate在通过某些子属性进行搜索时是否总是使用即时加载?
你能帮我解决这个问题吗。 我有两门课。一个是设备,第二个是设备生成的警报。 设备类看起来像Hibernate在通过某些子属性进行搜索时是否总是使用即时加载?,hibernate,lazy-loading,Hibernate,Lazy Loading,你能帮我解决这个问题吗。 我有两门课。一个是设备,第二个是设备生成的警报。 设备类看起来像 public class Device { private Long deviceId; private String deviceName; @OneToMany private List<Alert> alerts; } public class Alert { private Long deviceId; private Stri
public class Device
{
private Long deviceId;
private String deviceName;
@OneToMany
private List<Alert> alerts;
}
public class Alert
{
private Long deviceId;
private String alertText;
private String alertType;
private Date alertTime;
}
此方法的问题是,生成的SQL查询检索所有警报,然后应用结果转换器。
看起来像这样
select deviceID,deviceName,alertText,alertType,alertTime from devices d, alerts a left join a.deviceID=d.deviceID;
这个查询效率不高。如果警报表很大,则需要几分钟的时间。
因此,我有一些问题:
- 将添加
alertCriteria.add(Resrictions.between(“alertTime”)、开始日期、结束日期)代码>总是导致在一次选择中获取警报?如何避免呢
- 在不使用ResultTransformer的情况下,如何使所有不同的设备都具有警报
在实现第二个示例后,我在hibernate代码中获得了NPE: java.lang.NullPointerException 位于org.hibernate.loader.CriteriaQueryTranslator.getProjectedTypes(CriteriaQueryTranslator.java:362) 位于org.hibernate.criteria.SubqueryExpression.createAndSetInnerQuery(SubqueryExpression.java:153) 位于org.hibernate.criteria.SubqueryExpression.toSqlString(SubqueryExpression.java:69) 位于org.hibernate.loader.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:380) 位于org.hibernate.loader.criteria.CriteriaJoinWalker(CriteriaJoinWalker.java:102) 位于org.hibernate.loader.criteria.CriteriaJoinWalker(CriteriaJoinWalker.java:82) 位于org.hibernate.loader.criteria.CriteriaLoader.(CriteriaLoader.java:92) 位于org.hibernate.impl.SessionImpl.list(SessionImpl.java:1697)
在org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)回答1:当您按子属性筛选时,sql必须连接到子表以获取关联的根实体 回答2:如果您需要在给定范围内具有任何警报的设备
List<Device> devicesWithAlerts = session.createCriteria(Device.class, "device")
.createCriteria("alerts")
.add(Resrictions.between("alertTime", startDate, endDate))
.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE)
.List<Device>();
// or more efficiently because only wanted entities are loaded
List<Device> devicesWithAlerts = session.createCriteria(Device.class, "device")
.Add(Subqueries.PropertyIn("id", DetachedCriteria.For(Device.class)
.CreateCriteria("alerts")
.add(Resrictions.between("alertTime", startDate, endDate))
.SetProjection(Projections.Distinct(Projections.Id()))
))
.List<Device>();
List devicesWithAlerts=session.createCriteria(Device.class,“设备”)
.createCriteria(“警报”)
.add(Resrictions.between(“alertTime”、startDate、endDate))
.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE)
.List();
//或者更有效,因为只加载所需的实体
列出设备WithAlerts=session.createCriteria(Device.class,“设备”)
.Add(subquerys.PropertyIn(“id”),DetachedCriteria.For(Device.class)
.CreateCriteria(“警报”)
.add(Resrictions.between(“alertTime”、startDate、endDate))
.SetProjection(projects.Distinct(projects.Id()))
))
.List();
List<Device> devicesWithAlerts = session.createCriteria(Device.class, "device")
.createCriteria("alerts")
.add(Resrictions.between("alertTime", startDate, endDate))
.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE)
.List<Device>();
// or more efficiently because only wanted entities are loaded
List<Device> devicesWithAlerts = session.createCriteria(Device.class, "device")
.Add(Subqueries.PropertyIn("id", DetachedCriteria.For(Device.class)
.CreateCriteria("alerts")
.add(Resrictions.between("alertTime", startDate, endDate))
.SetProjection(Projections.Distinct(Projections.Id()))
))
.List<Device>();