2012-04-25 4 views
1

Donc, je n'arrive pas à résoudre ce problème et je n'arrive pas à le faire fonctionner correctement.La mise en correspondance Hibernate renvoie plusieurs objets identiques lors de l'exécution de requêtes paginées avec des critères supplémentaires.

Les choses semblent bien fonctionner quand j'utiliser mon HibernateUtil.get (clazz, PKID) méthode, mais quand j'essayer d'utiliser le HibernateUtil.pagedQuery (clazz, critère, start, stop) je reçois plusieurs objets identiques revenu.

Par exemple, s'il y avait 3 employés affectés au rôle 1, puis en cours d'exécution ...

Role role = HibernateUtil.get(Role.class, new Integer(1)); 

... fonctionne comme prévu. Cependant, si je cours ...

List<Criterion> c = new ArrayList(); 
c.add(Restrictions.eq("roleTypeSeqNo", new Integer(1))); 
List<Role> roles = (List<Role>) phi.util.hibernate.HibernateUtil.pagedQuery(Role.class, c, 0, 50); 

... renvoie une liste de 3 rôles identiques. Tous ceux qui représentent le rôle 1.

Si quelqu'un pouvait me guider sur le bon chemin, je l'apprécierais vraiment.

Merci d'avance!

est ici une version abrégée de mes cours

@Entity 
@Table(name="ASSIGNMENTS") 
public class Assignment implements Serializable { 
    @EmbeddedId 
    private AssignmentPK pk; 
    // After coming across many errors I finally caved and reverted roleTypeSeqNo back to just an Integer. 
    private Integer roleTypeSeqNo; 
    private String status; 
    private String location; 
} 

@Embeddable 
public class AssignmentPK implements Serializable { 
    @ManyToOne 
    @JoinColumn(name="EMPLID") 
    private Employee employee; 
    @Column(name="PRIORITY_NO") 
    private String priorityNo; 
} 

@Entity 
public class Employee implements Serializable { 
    @Id 
    private Integer emplId; 
    private String name; 
} 

@Entity 
public class Role implements Serializable { 
    @Id 
    private Integer roleTypeSeqNo; 
    private Integer reportsToRole; 
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="roleTypeSeqNo") 
    @JoinTable(
     name="ASSIGNMENTS" 
     , joinColumns={@JoinColumn(name="ROLE_TYPE_SEQ_NO")} 
     , inverseJoinColumns={ 
      @JoinColumn(name="EMPLID"), 
      @JoinColumn(name="PRIORITY_NO") 
     } 
) 
    private List<Assignment> assignments; 
} 

public class HibernateUtil { 
    public static Object get(Class clazz, Serializable pkId) { 
     Session session = getSession(); 
     Transaction transaction = session.beginTransaction(); 

     Object obj = session.get(clazz, pkId); 

     transaction.commit(); 
     session.close(); 

     return obj; 
    } 

    public static List pagedQuery(Class clazz, List<Criterion> criterion, Integer start, Integer size){ 
     Session session = getSession(); 
     try { 
      Transaction transaction = session.beginTransaction(); 

      DetachedCriteria dCriteria = DetachedCriteria.forClass(clazz); 
      for(Criterion c : criterion){ 
       dCriteria.add(c); 
      } 
      dCriteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); 
      dCriteria.setProjection(Projections.id()); 

      Criteria criteria=session.createCriteria(clazz); 
      criteria.add(Subqueries.propertyIn("id", dCriteria)); 
      criteria.setFirstResult(start); 
      criteria.setMaxResults(size); 

      List records = criteria.list(); 

      transaction.commit(); 

      return records; 
     } catch (Exception e) { 
      Logger.getLogger("HibernateUtil").log(Level.SEVERE, "There was an EXCEPTION THROWN!!!", e); 
      return null; 
     } finally { 
      session.close(); 
     } 
    } 
} 
+0

pouvez-vous s'il vous plaît poster votre fichier de cartographie? – rags

+0

Je n'ai pas de fichier de correspondance. J'utilise des annotations. – hypno7oad

Répondre

5
dCriteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); 

devrait être sur les principaux critères

criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); 

De plus il n'y a pas besoin de la sous-requête là. Ce qui suit est suffisant

Criteria criteria = session.createCriteria(clazz); 

    for(Criterion c : criterions){ 
     criteria.add(c); 
    } 

    criteria.setFirstResult(start); 
    criteria.setMaxResults(size); 

    List records = criteria.list(); 
+0

A travaillé! Merci beaucoup! – hypno7oad

+0

Pouvez-vous expliquer pourquoi cela est nécessaire? Que fait CriteriaSpecification.DISTINCT_ROOT_ENTITY? Dans quelles situations obtenons-nous plusieurs résultats pour le même objet? – jhegedus

+0

si vous joignez ensemble une table parent et une table enfant (1-n), les enregistrements parents sont dupliqués 'SELECT p. *, C. * FROM parenttable p JOIN la table des enfants c ON p.Id = c.parent_id'. Hibernate va émettre un listelement par ligne retournée mais utilisera la même référence si le parentrecord est le même. DISTINCT_ROOT_ENTITY filtre les objets parents dupliqués dans le résultat afin que vous récupériez une liste d'objets parents distincts. – Firo

Questions connexes