membersound
membersound

Reputation: 86747

How to cascade persist a @ManyToOne relation (TransientPropertyValueException)?

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

Answers (2)

Pras
Pras

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

Nicholas Robinson
Nicholas Robinson

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

Related Questions