Reputation: 1367
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
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
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