3
votes

Using JPA with EclipseLink I have 2 classes: User and Address.

Simplifying, in the same transaction I creates a new user, a new address and add that address to the user knowing that each user can have many addresses:

User = new User();
Address address= new Address();
user.addAddress(address);

This is the mapping in User class:

@OneToMany(mappedBy = "idUser")
private Set<Address> addresses;

This is the mapping in Address class:

@ManyToOne(cascade = { javax.persistence.CascadeType.REFRESH, javax.persistence.CascadeType.MERGE })
@JoinColumn(name = "id_user", referencedColumnName = "id", nullable = false)
private User user;

I am using a Spring Data JPA Custom Repository where I inject the entitymanager and is called from a service:

public void saveUser(TUsuario user) 
{
    em.persist(user);
}

After, I persist the Address

address.setDay(1);
address.setMonth(2);
address.setYear(3);
address.setUser(user);

public void saveUserAddress(Address address) 
{
    em.persist(address);
} 

And finally, when the service method has finished, the transaction is made.

When I try to commit the thansaction an error raises:

'A new object was found through a relationship that was not marked cascade PERSIST'

If I mark the user addresses list as cascade PERSIST, then eclipselink tries to save the user twice (I think one when I persist the user and second when the user address is persisted).

How can I do it to eclipselink not to persist it, but detect it as an existing object?

PS: I tried to use merge instead of persist and didn't work.

1
Sorry, it was a typo. It wasn't session class but address classAntonio Acevedo
I have test both ways and it keeps wrong: 1) simply add the address object to the user address list and save the user object (that's containing the new Address). 2) create the address object, add it the user object and save the address object.Antonio Acevedo

1 Answers

4
votes

One error is:

@OneToMany(mappedBy = "user")//you have idUser

Then add Try the following:

User user = new User();
Address address = new Address();

address.setUser(User);
user.addAddress(address);

em.persist(user);//you can delete this, if you add PERSIST (address.user field) to the @ManyToOne(cascade = { javax.persistence.CascadeType.REFRESH, javax.persistence.CascadeType.MERGE })
em.persist(address);