2009-12-02 45 views
10

Tengo un usuario de clase. Un usuario puede ser un amigo con muchos otros usuarios. La relación es mutua. Si A es amigo de B, B es amigo de A. También quiero que cada relación almacene datos adicionales, por ejemplo, la fecha en que dos usuarios se hicieron amigos. Así que esta es una relación de muchos a muchos en la misma tabla con columnas adicionales. Sé que se debe crear una Amistad de clase media (que contenga dos identificadores de usuario y una columna para la fecha). Pero me estoy quedando corto al mapear esto con Hibernate. Lo que me detiene es que la asignación es a la misma tabla. Puedo resolverlo, si la relación de muchos a muchos estaba entre dos tablas diferentes.Many-to-many en la misma tabla con columnas adicionales

Respuesta

7

Usted ha dicho

muchos-a-muchos relación en la misma mesa

No es una buena idea. Es una pesadilla para mantener.

Prueba este lugar

@Entity 
public class Friend { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Integer friendId; 

    @Column 
    private String name; 

    @OneToMany(mappedBy="me") 
    private List<MyFriends> myFriends; 

} 

@Entity 
public class MyFriends { 

    @EmbeddedId 
    private MyFriendsId id; 

    @Column 
    private String additionalColumn; 

    @ManyToOne 
    @JoinColumn(name="ME_ID", insertable=false, updateable=false) 
    private Friend me; 

    @ManyToOne 
    @JoinColumn(name="MY_FRIEND_ID", insertable=false, updateable=false) 
    private Friend myFriend; 

    @Embeddable 
    public static class MyFriendsId implements Serializable { 

     @Column(name="ME_ID", nullable=false, updateable=false) 
     private Integer meId; 

     @Column(name="MY_FRIEND_ID", nullable=false, updateable=false) 
     private Integer myFriendId; 

     public boolean equals(Object o) { 
      if(o == null) 
       return false; 

      if(!(o instanceof MyFriendsId)) 
       return false; 

      MyFriendsId other = (MyFriendsId) o; 
      if(!(other.getMeId().equals(getMeId())) 
       return false; 

      if(!(other.getMyFriendId().equals(getMyFriendId())) 
       return false; 

      return true; 
     } 

     public int hashcode() { 
      // hashcode impl 
     } 

    } 


} 

respecto,

+0

Gracias por su respuesta. Pero tengo una pregunta. ¿Por qué se inserta "insertable = false" en las relaciones @ManyToOne? Si lo elimino, entonces funciona. De lo contrario, MyFriends no se conserva correctamente. No soy un experto en Hibernate, entonces probablemente no entiendo nada. –

+0

Ok, no he usado un EmbeddedId como tú, sino solo otra columna de identificación. Has puesto el insertable = falso porque EmbeddedId se ocupa de él. Su respuesta es aceptada :) –

+0

Ha notado por qué. Cuando dos propiedades comparten la misma columna, es una buena idea poner las configuraciones al respecto en una sola propiedad. De lo contrario, Hibernate se quejará de algunos errores. –

2

No estoy seguro de que esto se ajuste a su caso, pero pruébelo.

@Entity 
public class Friend { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private int friendId; 

    @Column 
    private String name; 

    @ManyToMany(mappedBy="owner") 
    private List<Friendship> friendships; 
} 

@Entity 
public class Friendship { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private int friendshipId; 

    @OneToOne 
    private Friend owner; 

    @OneToOne 
    private Friend target; 

    // other info 
} 
1

que tenían el mismo problema. Puede intentar algo como esto:

<class name="Friend" entity-name="RelatedFriend" table="FRIENDS"> 
    <id name="id" type="long"> 
     <generator class="native" /> 
    </id> 

    <!-- *** --> 

    <set name="relatedFriends" table="RELATED_FRIENDS"> 
     <key column="FRIEND_ID" /> 
     <many-to-many column="RELATED_FRIEND_ID" class="Friend" entity-name="RelatedFriend"/> 
    </set> 
</class> 
Cuestiones relacionadas