我们的开发团队遇到了很大的问题。
我们正在使用Hibernate,并且我们有一些实体在两个传递的一对多关系中相关。主对象是一个具有Property实例列表的Group,每个Property包含一个Values列表。
(映射向前)
我们有两个主要问题:
A)在进行HQL查询,Criteria Query或SQLQuery时,JOIN或WHERE子句中应用的条件无关紧要,Hibernate总是为我们检索所有底层对象。例如,如果我使Criteria或SQL只获取Group对象,Hibernate来了(懒惰或不懒惰)获取所有Property和Value实例。我们想要控制它。我们想做左连接并只得到里面没有值的属性(Hibernate删除这些没有值的属性)
B)在进行查询(例如SQL)时,它会在日志中显示我们想要的SQL代码。一切似乎都很完美。但之后它会在列表中显示每个实例而不应用条件,只能通过id获取它们,我们可以保证这一点,因为使用lazy =“true”我们会在日志中看到“加载多对一”查询。
我们可以在hibernate配置,获取模式/策略,映射配置或任何地方做些什么吗?我正在考虑现在进行结果变换器。
如果有人给我一个提示或告诉我在哪里找到解决这个问题的方法,我将不胜感激。我们对如何实现这一点感到困惑,但它必须是一种方式。
提前致谢
查询:
Criteria lstCriterios = this.getSession().createCriteria(CardGroup.class, CARD_GROUP)
.add(Restrictions.eq(ID_CATEGORY, idCategory));
lstCriterios.createAlias("listProperty", "listProperty", CriteriaSpecification.LEFT_JOIN);
if (clusterId != null) {
lstCriterios.add(Restrictions.or(
Restrictions.isNull("listPropertyValue" + ".value"),
Restrictions.and(Restrictions.eq("listPropertyValue" + ".clusterId", clusterId),
Restrictions.eq("listPropertValue" + ".companyWarehouseId", idCompanyWarehouse))));
lstCriterios
.createAlias("listProperty" + "." + "listPropertyValue", "listPropertyValue",
CriteriaSpecification.LEFT_JOIN,
Restrictions.eq("listPropertyValue" + ".clusterId", clusterId));
} else {
lstCriterios.createAlias("listProperty" + ".listPropertyValue", "listPropertyValue",
CriteriaSpecification.LEFT_JOIN);
}
lstCriterios.add(Restrictions.eq(ID_CATEGORY, idCategory));
lstCriterios.add(Restrictions.eq("listProperty" + ".groupId", idGroup));
lstCriterios.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
/*
* Sorting
*/
lstCriterios.addOrder(Order.asc("order"));
lstCriterios.addOrder(Order.asc("listProperty" + ".order"));
lstCriterios.addOrder(Order.asc("listPropertyValue"+ ".clusterId")); // Agrupacion, podría ser nulo
lstCriterios.addOrder(Order.asc("listPropertyValue"+ ".propertyId")); // Propiedad
lstCriterios.addOrder(Order.asc("listPropertyValue"+ ".id"));
return lstCriterios.list();
组映射:
<list name="listProperty"
table="FICHA_PROPIEDAD" schema="${db2.siglo.schema}"
inverse="false" cascade="all" >
<key column="ID_FICHA_GRUPO" not-null="false" />
<list-index column="ORDEN" base="1"/>
<one-to-many
class="com.company.aslo.appwebsiglo.model.card.property.property.CardProperty" />
</list>
属性映射:
<bag name="listPropertyValue"
table="FICHA_PROPIEDAD_VALOR" schema="${db2.siglo.schema}"
inverse="false" cascade="all">
<key column="ID_FICHA_PROPIEDAD" not-null="false" />
<one-to-many
class="com.company.aslo.appwebsiglo.model.card.propertyvalue.propertyvalue.CardPropertyValue" />
</bag>
答案 0 :(得分:0)
似乎我们的模型设计很糟糕,我们没有意识到如果数据库表FICHA_PROPIEDAD_VALOR具有复合键,我们不能只映射复合键中的一个属性,因为它会给我们带来意想不到的结果。
由于这个和嵌套对象,我们还有Hibernate使用的hashCode()和equals()方法的错误实现。
我之前使用ResultTransformer从SQLQuery获取行来解决了这个问题,但是在重构和更改模型设计之后我们得到了Hibernate解决方案。