Hibernate critères de collecte de valeurs
Je vais essayer de mettre sur pied un complexe requête de l'utilisation d'Hibernate. J'ai été en se penchant vers les Critères, mais je commence à soupçonner qu'il n'est pas possible, et donc toutes les suggestions seraient utiles.
J'ai une entité de la structure comme suit:
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;
}
Ces entités sont liées comme vous le souhaitez:
value.attribute_id --> attribute.id
value.instance_id --> instance.id
Maintenant, je voudrais être en mesure de prendre un ensemble de paires attribut/valeur (Chaînes de caractères) et de trouver toutes les occurrences contenant tous d'entre eux. En Valeur, un seul des attributs et localAttributeName sont non-nulles, de sorte que le nom de l'attribut peut correspondre localAttributeName ou de l'attribut.nom. Et pour compliquer les choses, une dernière fois, l'index unique sur la Valeur est sur (l'instance, attribut, valeur) ou (instance, localAttributeName, valeur) - qui est, au sein d'une Instance, tout Attribut peut avoir plusieurs Valeurs.
C'est ce que j'ai à ce jour:
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();
}
Basé sur les recherches que j'ai fait, ce que j'ai essayé pour Faire quelque chose de section est:
//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"));
Mais cela lève l'exception ci-dessous, ce qui je pense me dit que je ne peut pas le faire avec des Critères, mais j'aimerais apprendre autrement:
java.lang.NullPointerException
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getProjectedTypes(CriteriaQueryTranslator.java:341)
Quelle serait la meilleure façon de faire cela?
OriginalL'auteur Jon | 2011-01-29
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé la solution après quelques heures de taper sur elle. Espérons que cela est utile à d'autres. Il y avait trois principaux points que je devais me résoudre à faire ce faisable:
J'ai mis en évidence chacun de ces éléments dans le code ci-dessous.
D'abord, pour se débarrasser de l'exception, j'ai découvert que la sous-requête besoin d'une projection, a mis en évidence ci-dessous. J'ai juste fait une projection sur la propriété "id" de l'Instance.
Seconde, pour obtenir le rejoindre, j'ai utilisé les Critères.createCriteria() méthodes pour créer une jointure externe gauche. Parce que j'ai eu plusieurs conditions à différents niveaux de la rejoindre, je devais enregistrer le joint de Critères et de fixer des expressions pour eux séparément. Cela m'a permis de faire de mon OU de l'expression de la sous-requête.
Enfin, j'ai dû ajouter un eqProperty() de la clause à la carte de la sous-requête en retour pour les principaux Critères. Tout comme il aurait besoin d'être dans le SQL, j'ai utilisé: exemple.id = je.id. Parce que j'avais déjà pensé à l'Instance Critères de "je" et a été l'ajout de cette clause pour les Critères de Valeur, ce qui traduit le SQL: v. instance_id = je.id.
Voici le code de travail:
Hey @Jon, pourriez-vous m'aider avec ce problème? Voici le lien stackoverflow.com/questions/22919886/...! Merci! Est sur quelque chose d'assez similaire!
Quelle est la version d'Hibernate est-ce la bonne réponse?
OriginalL'auteur Jon