2011-06-08 27 views
6

Me pregunto cómo escribir un equals() y hashCode() correctos para Hibernate Entities que tienen una relación Lazy Loaded ManyToOne con otra entidad que es importante como una clave de negocios. Tenga en cuenta que ya leí the Hibernate documentation on this topic y sé que debo/no debo usar el ID del objeto.Hibernate/JPA es igual a() y hashCode() con Identificador de carga de Lazy Business

Para aclarar, aquí un ejemplo:

public class BusinessEntity implements Serializable 
{ 
    //for simplicity, here just the important part 
    private String s; 

    @ManyToOne(fetch= FetchType.LAZY) 
    private ImportantEntity anotherEntity; 

    @Override 
    public boolean equals(Object obj) 
    { 
     //Here I would like to call something like 
     // (obj.getAnotherEntity.getName.equals(getAnotherEntity.getName) && obj.getS().equals(getS()); 

     return true; 
    } 
} 

Por supuesto, esto es sólo un ejemplo simplificado. Pero espero poder explicar mi situación. ¿Alguien ha intentado algo así antes? No encontré nada relacionado con este tema.

+1

utilizando el ID de objeto es OK es algunas circunstancias - por ejemplo, si los nuevos objetos businessEntity no serán siendo creado Además, es posible que solo pueda usar el código equals/hash predeterminado según cómo se maneje su sesión. – david

Respuesta

3

Por simplicidad me salté el código de seguridad nulo. Pero la idea es crear propiedad adicional que persistirá nombre de la entidad y no exponerlo al mundo exterior

public class BusinessEntity implements Serializable 
{ 
    //for simplicity, here just the important part 
    private String s; 

    @ManyToOne(fetch= FetchType.LAZY) 
    private ImportantEntity anotherEntity; 

    private String anotherEntityName; 

    @Override 
    public boolean equals(Object obj) 
    { 
     if(BusinessEntity.class.isAssignableFrom(obj.getClasS())){ 
     BusinessEntity other = (BusinessEntity)obj; 
     return other.anotherEntityName. 
       equals(this.anotherEntityName) && 
       other.s.equals(this.s); 

     } 
     return true; 
    } 
    public void setAnotherEntity(ImportantEntity ie){ 
     anotherEntityName= ie.getName(); 
     anotherEntity = ie; 
    } 
} 
+0

Creo que entendí la idea. Pero, ¿no debería ser este un campo @Transient? –

+1

Bueno, si fuera transitorio, tendría que iniciarlo en la carga de entidad utilizando la devolución de llamada de @PostLoad y, si no es transitorio, no tiene que consumir otraEntidad solo para calcular hashCode() y equals(), por lo que es solo un enfoque de optimización pero produce redundancia de datos (debe decidir qué es lo mejor para usted) –

2

En los equivalentes debe usar instanceof para comparar los tipos y los captadores de las propiedades que debe incluir.

instanceof se utiliza debido a las clases de proxy que hibernate utiliza y los getters se utilizan para habilitar las cargas perezosas.

+0

no muy bien formulado pero me ayudó mucho, thx – avalancha