onetomany one manytoone many ejemplo hibernate one-to-one many-to-one

hibernate - ejemplo - Hibernar ManyToOne vs OneToOne



onetomany jpa bidirectional (4)

No puedo ver ninguna diferencia en el esquema de una relación Many-To-One vs una relación OneToOne:

@Entity public class Order { @ManyToOne @JoinColumn(nullable = false) private Address address;

vs

@Entity public class Order { @OneToOne @JoinColumn(nullable = false) private Address address;

¿Hay alguna diferencia?


Esto está muy bien ilustrado en la documentación de Doctrine ORM de Association Mapping (no creo que sea específica de Hibernate).

ManyToOne:

Considere las tablas User y Address mientras que la columna User.address_id tiene una asociación ManyToOne con la columna Address.id . Este sería el SQL:

CREATE TABLE User ( id INT AUTO_INCREMENT NOT NULL, address_id INT DEFAULT NULL, PRIMARY KEY(id) ) ENGINE = InnoDB; CREATE TABLE Address ( id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id) ) ENGINE = InnoDB; ALTER TABLE User ADD FOREIGN KEY (address_id) REFERENCES Address(id);

Doce y cincuenta y nueve de la noche:

Ahora, considere las tablas Product y Shipment , mientras que la columna Product.shipment_id tiene una asociación OneToOne (unidireccional) a la columna Shipment.id . Este sería el SQL:

CREATE TABLE Product ( id INT AUTO_INCREMENT NOT NULL, shipment_id INT DEFAULT NULL, UNIQUE INDEX UNIQ_6FBC94267FE4B2B (shipment_id), PRIMARY KEY(id) ) ENGINE = InnoDB; CREATE TABLE Shipment ( id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id) ) ENGINE = InnoDB; ALTER TABLE Product ADD FOREIGN KEY (shipment_id) REFERENCES Shipment(id);

La diferencia es la cláusula de UNIQUE INDEX que dicta que no debe haber un shipment.id ocurra dos veces en la tabla de Product . Esto garantiza la asociación One ToOne.


Esto indica que ambos lados de la relación se atienden mejor teniendo la misma clave principal. Tiene más sentido de esta manera, ya que ambos lados están asociados con un solo orden en el caso de la relación @OneToOne .


Normalmente, debe existir una restricción única en la columna de unión address_id en el caso de una asociación OneToOne, para garantizar que solo una Orden pueda tener una dirección determinada.


Se ven exactamente iguales en el esquema, pero hay una diferencia en la capa de hibernación.

Si intentas algo así:

Address address = new Address(); Order order1 = new Order(); order1.setAddress(address); Order order2 = new Order(); order2.setAddress(address); save();

Todo estará bien. Pero, después de guardar si intentas obtener Orden:

@OneToOne case: org.hibernate.HibernateException: More than one row with the given identifier was found: 1 @ManyToOne case: SUCCESS

Por supuesto, su clase de Dirección debe verse diferente en ambos casos.