Я пытаюсь собрать сложный запрос, используя 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 только один из атрибутов и localAttributeName не являются нулевыми, поэтому имя атрибута может соответствовать либо localAttributeName, либо attribute.name. И чтобы усложнить ситуацию в последний раз, уникальный индекс на Value включен (экземпляр, атрибут, значение) или (экземпляр, localAttributeName, значение), то есть внутри экземпляра любой атрибут может иметь несколько значений.
Это то, что у меня есть до сих пор:
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 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"));
Но это вызывает исключение ниже, которое, как я подозреваю, говорит мне, что я не могу сделать это с помощью критериев, но мне бы хотелось узнать иначе:
java.lang.NullPointerException
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getProjectedTypes(CriteriaQueryTranslator.java:341)
Каким будет лучший способ сделать это?