I have User and Address classes as follows:
class User
{
...
...
@OneToOne( cascade=CascadeType.ALL)
@JoinColumn(name="addr_id")
private Address address;
}
class Address
{
...
...
@OneToOne(mappedBy="address")
private User user;
}
Here my assumption is with this domain model I can associate one address to only one user(user.addr_id should be unique).
But with this domain model, I am able to create multiple users and associate them to the same address.
User u1 = new User();
//set data
Address addr1 = new Address();
//set data
u1.setAddress(addr1);
...
session.save(u1);
–> this is creating one address record with addr_id=1 and inserting one user record in user table with addr_id=1. Fine.
Again,
User u2 = new User();
//set data
Address addr1 = (Address) session.load(Address.class, 1);
//set data
u2.setAddress(addr1);
...
session.save(u2);
–> This is creating second user record and associating to existing address with addr_id=1, which is not desired.
I can use @OneToOne(..)@JoinColumn(name=”addr_id”, unique=true) to prevent this.
But what will be the difference of using @OneToOne rather than @ManyToOne(.., unique=true).
@OneToOne itself should impose “unique=true” condition..right?
-Siva
@OneToOne is annotating the Java to express the idea of the relationship between the two classes. If this was a @OneToMany then we’d have a collection instead. So reading the annotations we understand the realtionships, and the JPA runtime also understands those.
The actual policing of the one-to-one is performed in the database – we need the schema to have the uniqueness constraints. The @JoinColumn expresses how that relationship is manifest in the DatabaseSchema.This can be useful if we are generating the schema.
However in many cases we use bottom-up tools to generate the Java from the schema. In this case there’s no actual need for the Java annotations to reflect the database constraints, from a Java perspective we just see the relationship.
An intelligent compiler might warn us if the semantics of our @JoinColumn doesn’t match the @oneToOne, but I’m not sure whether current implementations do that.