Domanda

I can't see any difference in the schema of a Many-To-One relationship vs a OneToOne relationship:

@Entity
public class Order {

    @ManyToOne
    @JoinColumn(nullable = false)
    private Address address;

vs

@Entity
public class Order {

    @OneToOne
    @JoinColumn(nullable = false)
    private Address address;

Is there any difference?

È stato utile?

Soluzione

They look exactly the same on schema but there is difference on Hibernate Layer.

If you try something like that:

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

Everything will be OK. But, after save if you try get Order:

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

@ManyToOne case:
SUCCESS

Of course, your Address class should looks different in both cases.

Altri suggerimenti

There should normally be a unique constraint on the address_id join column in the case of a OneToOne association, to guarantee that only one Order can have a given address.

TL;DR: The schema might look the same at first glance, but the OneToOne may have an additional UNIQUE INDEX constraint. This guarantees the OneToOne association.

This is nicely illustrated by the Doctrine ORM documentation of Association Mapping (I don't think it's specific to Hibernate).

An example:

ManyToOne:

Consider the tables User and Address while the column User.address_id has a ManyToOne association to the Address.id column. This would be the 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); 

OneToOne:

Now, consider the tables Product and Shipment, while the column Product.shipment_id has a OneToOne (unidirectional) association to the Shipment.id column. This would be the 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);

The only difference is the UNIQUE INDEX directive which dictates there must not be a shipment.id occuring twice in the Product table. This guarantees the OneToOne association.

This indicates both sides of the relationship are best served by having the same primary key. It makes more sense this way since both sides are associated one and only one order in the case of the @OneToOne relationship.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top