Reputation: 86747
I want to create a DB mapping using hibernate
: each Person
may only have one single Address
, but the same address may be assigned to multiple persons (eg gamily members).
The following mapping does not work:
@Entity
public class Person {
@ManyToOne
@JoinColumn(name="fk_address_id", foreignKey = @ForeignKey(name="fk_addres"))
private Address address;
}
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String city;
private int zip;
private String street;
@OneToMany(mappedBy = "address", cascade = {CascadeType.ALL})
private Set<Person> persons;
}
@Transactional
public void create() {
Person person = new Person();
Address address = new Address();
address.setStreet("test 1");
address.setCity("test");
address.setZip(123);
person.setAddress(address);
dao.save(person);
}
Result:
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : Person.address -> Address
Why am I getting this exception, and how can I prevent it? I thought due to the cascading the address should automatically get saved?
Upvotes: 2
Views: 2101
Reputation: 1098
I don't really understand the answer given by Nicholas Robinson .. here is what's going on :
Person doesn't cascade changes to Address ... but Address does ... you then have to save the address
change
dao.save(person);
by
dao.save(address);
Upvotes: 1
Reputation: 1419
Add @Cascade({CascadeType.MERGE})
to private Set<Person> persons;
or change from ALL
to MERGE
. The problem is that you are making changes to Person and not saving them before saving Address. The Merge Cascade will do this for you.
Upvotes: 1