Stelium
Stelium

Reputation: 1367

Hibernate one to one allows many to one

I have created a unidirectional one-to-one relationship like this:

@Entity(name="person")
public class Person {

    @Id
    @GeneratedValue
    @Column(name = "pid", unique = true) // note 2
    private int id;

    // more fields

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="address_id", unique = true) // note 1
    private Address address;

    // rest of class
}

@Entity(name="address")
public class Address {

    @Id
    @GeneratedValue
    @Column(name = "aid", unique = true)
    private int id;

    // rest of class
}

note 1:

If I don't specify the "address_id" column to be unique like this

   @JoinColumn(name="address_id")

then it is not unique and I can have many persons refer to the same adress which is a many-to-one relation like this:

Person person1 = new Person();
Person person2 = new Person();
Address address  = new Address("21th street");
person1.setAddress(address);
person2.setAddress(address);

Shouldn't a one-to-one relation make the foreign key "address_id" unique by default?

note 2:

The id is not unique although I specify it. Why?

Upvotes: 2

Views: 1084

Answers (2)

JB Nizet
JB Nizet

Reputation: 691635

Hibernate doesn't enforce the uniqueness. That's the job of the database.

For your OneToOne, make sure there is a unique constraint on the address_id column. For the IDs, make sure there is a primary key constraint (which enforces uniqueness) on the ID columns.

If you generate the database using Hibernate DDL generation, Hibernate will use the attributes of the annotations: @Id will create a PK, and unique = true will generate a unique constraint.

But for any serious work, I would generate the schema by myself, using a tool like FlywayDB or Liquibase, which allows migrating your schema from version to version.

Upvotes: 2

user3973283
user3973283

Reputation:

As per the JPA spec 2.10.3.1 there should be a unique constraint created by default

Table A contains a foreign key to table B. The foreign key column name is formed as the concatenation of the following: the name of the relationship property or field of entity A; "_"; the name of the primary key column in table B. The foreign key column has the same type as the primary key of table B and there is a unique key constraint on it.

So Hibernate seems to be contravening that part of the spec. I seem to remember that EclipseLink also does (or did) that. You should be able to find another question in Stackoverflow about it. DataNucleus did it right last I looked.

Upvotes: 0

Related Questions