1

I'm trying to run the code below, but I keep getting the error "Cannot merge an entity that has been removed".

My DB tables look like this:

banner
-id

banner_period
-id
-banner_id
-date

My Java code:

Banner b = getEntityManager().find(banner.getId());
List<BannerPeriod> bps = b.getBannerPeriodList();
for (BannerPeriod bp : bps) {
    getEntityManager().remove(bp);
}
// <-- removed code that adds periods here
b.setBannerPeriodList(bps);
getEntityManager().merge(b);

I can't seem to understand the logic in all this. Could anyone explain what it is, I'm missing here? I've tried to search for answers already, but I find it hard to define keywords that give me relevant results.

UPDATE:

Banner entity:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "bannerId")
private List<BannerPeriod> bannerPeriodList;

BannerPeriod entity:

@JoinColumn(name = "banner_id", referencedColumnName = "id")
@ManyToOne(optional = false)
private Banner bannerId;
Bjørn Stenfeldt
  • 1,432
  • 1
  • 18
  • 25

1 Answers1

2

List<BannerPeriod> bps still contains references to BannerPeriods. So when you call merge on b here is what happens.

merge on b
-> Cascade all on  bannerPeriodList
-> Iterate over bannerPeriodList and merge them
**ERROR** The values in bannerPeriodList have been removed.

Try this

bps.clear();
b.setBannerPeriodList(bps);
getEntityManager().merge(b);
Mark Robinson
  • 3,135
  • 1
  • 22
  • 37
  • Thank you for the suggestion. I've tried it. What happens is that the list is cleared, but merge doesn't apply the changes to the database. This is strange, because if I clear the list, verify the list is actually empty, add a new BannerPeriod to the list and then merge, the existing periods are still in the database, as is the new one. But when I look at the entities in Java, only the newly added BannerPeriod is in the list. It's not because the relation is broken in the database, because if I restart the server, all periods are back, both the old and new. – Bjørn Stenfeldt Oct 11 '11 at 15:11
  • 1
    What happens if you omit the merge? Could you also turn on SQL debugging in your ORM. It will help see what is happening behind the scenes. – Mark Robinson Oct 11 '11 at 16:15
  • Thanks!!! I never even considered doing that. It works when I omit the merge. I found that I must 1) run through the list and do a getEntityManager().remove(BannerPeriod) on each period, then 2) use clear() on the list of periods and finally 3) omit the merge. Only when I do all of those things combined do I avoid exceptions and get the same result both in my entities and my database. Hmm, I'm just thinking right this moment... maybe I have some sort of auto-commit turned on so everything commits twice. I will have to look into that. – Bjørn Stenfeldt Oct 12 '11 at 18:24