2010-11-29 1 views
12

Pour une raison quelconque, lorsque lazy = true sur toutes mes entités, la méthode equals() ne fonctionne pas correctement lorsqu'un côté est une entité paresseusement chargée et l'autre côté est une entité normale. Voici un exemple:Comment obtenez-vous equals() fonctionnant avec les entités Hibernate lorsque lazy = true?

if(activeTask.getTask().equals(task)) {...} 

Dans ce cas, la tâche du activeTask sera une procuration alors que le côté droit sera un régulier. Les égales() échoueront. Pour résoudre ce problème, je fais souvent des choses comme ceci:

if(activeTask.getTask().getId() == task.getId()) {...} 

Cela fonctionne, mais ce n'est pas idéal. Je préfère utiliser ma méthode equals().

Est-ce que quelqu'un a une bonne solution à ce problème? Cela ajoute vraiment au niveau de bruit de l'application pour avoir à penser à des choses comme ça.

Si je dis paresseux = faux, je n'ai pas besoin de traiter avec le proxy, et donc equals() fonctionnera. Mais cela a un impact très négatif sur la performance.

Il n'est simplement pas cool d'avoir à dire, "equals() fonctionne dans tous les cas, sauf si vous utilisez des proxies ... alors equals() n'est pas fiable."

Répondre

8

Je me rends compte que c'est une vieille question, mais il est encore sans réponse et les gens pourraient trébucher dessus.

J'ai eu le même problème il y a quelques jours. Dans le projet, nous utilisons une classe de base abstraite BasicEntityType, qui a juste un identifiant et Égale est mis en œuvre dans ladite classe de base:

@Override 
public final boolean equals(Object obj) { 
    if (this == obj) { 
     return true; 
    } 

    if (obj == null) { 
     return false; 
    } 

    Class<?> objClass = HibernateProxyHelper.getClassWithoutInitializingProxy(obj); 
    if (this.getClass() != objClass) { 
     return false; 
    } 

    if (id == null) { 
     return false; 
    } 

    return id.equals(((BasicEntityType) obj).getId()); 
} 

Il y a deux parties critiques dans ce code:

  • Première: Do ne vérifie pas directement l'égalité des classes, cela peut ne pas fonctionner avec l'objet donné.
  • Deuxième: Toutes les propriétés de l'objet donné doivent être accessibles en utilisant des méthodes. Ou vous pouvez déballer l'objet réel.
+0

impressionnant solution de contournement –

+0

Vous ne devez pas utiliser l'ID de la base de données en tant qu'égaux et en tant que hashcode lors de l'utilisation d'Hibernate. Voir http://docs.jboss.org/hibernate/core/4.0/manual/fr-FR/html/persistent-classes.html#persistent-classes-equalshashcode –

+0

HibernateProxyHelper.getClassWithoutInitializingProxy (obj) ne fonctionne pas avec l'héritage car il appelle org.hibernate.proxy.LazyInitializer.getPersistentClass() au lieu de org.hibernate.proxy.LazyInitializer.getImplementation() –

Questions connexes