I've a question about One to One unidirectional Mapping in Spring Boot. I've a Customer class with a One to One unidirectional mapping to an Address class.
But when I try to associate a new customer with an existing Address, the database is updated. So two Customers are now associated with the one Address.
As I understand it only one Customer should be associated with one unique Address. Do I understand the concept correctly, or am I doing something wrong in Spring Boot/ Spring Data JPA/ Hibernate?
Customer
@Entity
public class Customer {
@Id
private Long cId;
private String cName;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="aid")
private Address cAddr;
:
}
Address
@Entity
public class Address {
@Id
private Long aid;
private String town;
private String county;
:
}
data.sql
insert into address values (100, "New York", "NY");
insert into customer values (1, "John Smith", 100);
Application.java
@Override
public void run(String... args) throws Exception {
Customer c1 = new Customer((long)5, "Mr. Men");
Optional<Address> a100 = ar.findById((long)100);
c1.setcAddr(a100.get());
cr.save(c1);
}
There are 2 options on how to make @OneToOne relation: unidirectional and bidirectional: see hibernate doc.
When you scroll down a little bit you will find the following:
When using a bidirectional @OneToOne association, Hibernate enforces the unique constraint upon fetching the child-side. If there are more than one children associated with the same parent, Hibernate will throw a org.hibernate.exception.ConstraintViolationException
It means that you'll have the exception only on fetching and when you have a bidirectional association. Because Hibernate will make an additional query to find the dependent entities, will find 2 of them, which doesn't fit @OneToOne relation and will have to throw an exception.
One way to "fix" uniqueness for your entities, is to make cAddr
unique:
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="aid", unique=true)
private Address cAddr;
If you create your db tables, by setting hbm2ddl property this will add a unique constraint to the aid
column.
I really recommend to read the following:
@MapsId
.Also maybe you will come up to the idea to use @ManyToOne option (at least i can imagine that customer can have multiple addresses)