我正在尝试使用 Hibernate 组合一个复杂的查询。我一直倾向于标准,但我开始怀疑这是不可能的,所以任何建议都会有所帮助。
我有一个如下的实体结构:
public class Attribute {
private Integer id;
private String name;
private Set<Value> values;
}
public class Instance {
private Integer id;
private int instanceRef;
private Set<Value> values;
}
public class Value {
private Integer id;
private Attribute attribute;
private String localAttributeName;
private Instance instance;
private String value;
}
这些实体是相关的,如您所料:
value.attribute_id --> attribute.id
value.instance_id --> instance.id
现在,我希望能够获取一组属性/值对(字符串)并找到包含所有这些的所有实例。在 Value 中,attribute 和 localAttributeName 只有一个是非空的,因此属性名称可以匹配 localAttributeName 或 attribute.name。最后一次让事情复杂化的是,Value 上的唯一索引是 on (instance, attribute, value) 或 (instance, localAttributeName, value)——也就是说,在一个实例中,任何给定的属性都可能有多个值。
这是我到目前为止所拥有的:
public List<Instance> getMatchingInstances(Map<String, String> attrValues) {
Criteria crit = session.createCriteria(Instance.class, "i");
for(Map.Entry<String, String> entry : attrValues) {
DetachedCriteria valueCrit = DetachedCriteria.forClass(Value.class, "v");
// Do something here with valueCrit
crit.add(Subqueries.exists(valueCrit));
}
return crit.list();
}
根据我所做的研究,我为“做某事”部分所做的尝试是:
// This would only check localAttributeName and not attribute.name.
// That's okay -- once I get the rest to work, I can figure this out.
valueCrit.add(Restrictions.eq("localAttributeName", entry.getKey());
valueCrit.add(Restrictions.eq("value", entry.getValue());
valueCrit.add(Restrictions.eqProperty("v.instance_id", "i.id"));
但这会引发下面的异常,我怀疑它告诉我我不能用 Criteria 做到这一点,但我很想学习其他方式:
java.lang.NullPointerException
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getProjectedTypes(CriteriaQueryTranslator.java:341)
这样做的最佳方法是什么?