2011-11-19 22 views
7

Tengo problemas para entender la diferencia entre @OneToMany y @ManyToMany. Cuando uso @OneToMany, de forma predeterminada crea una JoinTable y si agrega el atributo mappedBy, tendrá una relación bidireccional entre dos entidades.Diferencia entre utilizar @OneToMany y @ManyToMany

Tengo un Question que pueden pertenecer a muchos Categories, y uno Category pueden pertenecer a muchos Questions. No entiendo si debería usar @ManyToMany o @OneToMany porque para mí parece exactamente lo mismo, pero probablemente no lo sea.

¿Alguien podría explicarlo?

Respuesta

15

Bueno, la diferencia está en el diseño que intentas reflejar utilizando objetos.

En su caso, cada Question se puede asignar a múltiples Categories - por lo que es un signo de la relación @*ToMany. Ahora usted tiene que decidir si:

  • cada Category sólo puede tener un Question asignados al mismo (que dará lugar a una única restricción lo que significa que ninguna otra categoría puede hacer referencia a la misma pregunta) - esto sea ​​@OneToMany relación,
  • cada Category puede tener múltiples Questions asignado a él (no habrá restricción única en la tabla Category) - esto será @ManyToMany relación.

@OneToMany (Pregunta -> Categoría)

Esta relación puede ser representada por unirse tabla sólo si se define explícitamente el uso de @JoinTable o cuando se trata de una relación unidireccionalen la que el lado propietario es el lado 'Uno' (significa que en la entidad Question tiene una colección de Categories, pero en el Categories no tiene ninguna referencia al Question).

Si lo piensas bien, parece bastante razonable que se use la tabla de unión. No hay otra manera en que el DBMS pueda guardar una conexión entre una fila en la tabla Question con varias filas en la tabla Categories.

Sin embargo, si desea modelar una relación bidireccional, debe especificar que Category (lado "Muchos") es el lado propietario de la relación.En este caso, el DBMS puede crear una columna de unión con clave externa en la tabla Category porque cada fila Category se puede conectar con una sola Question.

De esta forma, no tiene ninguna tabla de unión sino claves externas simples (aún, como se indicó al principio, puede forzar la creación de la tabla de unión utilizando @JoinTable).

@ManyToMany

Esta relación debe ser representado como una tabla de unión. Básicamente funciona muy similar a la relación unidireccional @OneToMany, pero en este caso puede tener varias filas de Question unidas con varias filas desde Categories.

+0

Awesome explanation. Debería tener muchos más upvotes. – LppEdd

0

@ManyToMany las relaciones tienen claves foráneas mutuamente referenciales en ambos lados de la relación. A veces, esta relación está mediada por una tabla contigua.

@OneToMany las relaciones tienen una clave externa en el lado "uno" y no en el lado "muchos". En una relación @OneToMany, un objeto es el "padre" y el otro es el "niño". El padre controla la existencia del niño.

Recuerde que una relación bidireccional @ManyToMany no tiene que ser simétrica.

0

En su pregunta & Categorías caso, debe usar @ManyToMany relación. @ManyToMany significa básicamente que "una pregunta puede pertenecer a muchas categorías al mismo tiempo" y "una categoría puede contener muchas preguntas al mismo tiempo". Se creará automáticamente una nueva tabla para almacenar las asignaciones. Su código se vería así:

@Entity 
public class Question implements Serializable { 
    ... 
    @ManyToMany 
    private List<Category> categories; 
    ... 
} 

@Entity 
public class Category implements Serializable { 
    ... 
    @ManyToMany 
    private List<Question> questions; 
    ... 
} 

Si utiliza la relación @OneToMany para sus preguntas y categorías (digamos Categoría en el lado Uno y preguntas sobre el otro), esto significa que "una pregunta que sólo puede pertenecer a una Categoría "y" una Categoría pueden contener muchas Preguntas al mismo tiempo ". No se necesita una nueva tabla para almacenar la asignación. En su lugar, se creará automáticamente un nuevo campo en el lado Muchos para registrar la ID del lado Uno. Su código se vería así:

@Entity 
public class Question implements Serializable { 
    ... 
    @ManyToOne 
    private Category theCategory; 
    ... 
} 

@Entity 
public class Category implements Serializable { 
    ... 
    @OneToMany(mappedBy="theCategory") 
    private List<Question> questions; 
    ... 
}