Reputation: 2765
I'm trying to move an entity (JPA) from one list to another list.
The problem is that the entity gets deleted instead of being moved (in the database).
The model (simplified):
@Entity
public class Group {
@Id
@GeneratedValue
@Column(name = "Id")
private long id;
@OneToMany(mappedBy = "group", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Item> items;
public Group() {
this.items = new ArrayList<>();
}
public List<Item> getItems() {
return items;
}
public long getId() {
return id;
}
}
@Entity
public class Item {
@Id
@GeneratedValue
@Column(name = "Id")
private long id;
private Group group;
public Item() {
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public long getId() {
return id;
}
}
The move operation is performed this way:
oldGroup.getItems().remove(item);
item.setGroup(newGroup);
newGroup.getItems().add(item);
Debugging shows that the lists are correctly updated but JPA is somehow unable to detect that the entity is used somewhere else and only cares about the CascadeType.ALL
and orphanRemoval = true
.
Note: it works when moving an entity from the first group to the second group but not the opposite.
Upvotes: 2
Views: 1055
Reputation: 20608
From the definition of OneToMany
:
/**
* (Optional) Whether to apply the remove operation to entities that have
* been removed from the relationship and to cascade the remove operation to
* those entities.
* @since Java Persistence 2.0
*/
boolean orphanRemoval() default false;
So I'm afraid that as soon as you remove the entity from the relationship, it is scheduled to be removed.
If you want to keep the orphanRemoval
and avoid this issue, you could simply do the change on the Item
side without altering the collection:
item.setGroup(newGroup);
without getItems().remove
/add(item)
.
If you really need to update the collection, you might detach
the oldGroup
before performing the change in the collection.
Notice though that if you are in the context of a web app, this is usually not a problem if your URL's are RESTful:
POST
to perform the change;Upvotes: 1
Reputation: 692121
orphanRemoval = true
means: if the entity is removed from the list, delete it. So it's precisely what you do not want to happen.
So just remove that attribute from your annotation (or set it to false).
Upvotes: 1