Hibernate:collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance
Solution 1
Most common problem is to overwrite your collection rather than add to it.
If you happend to do something like that :
post.dateActiveScheduleItems = list;
This may cause following problem. Rather than that try this.
post.dateActiveScheduleItems.addAll(list);
You should work with one instance of your collection, just clear it, add to it, never overwrite.
Solution 2
Rempove orphanRemoval=true from here.
@OneToMany(mappedBy = "schedule",cascade = CascadeType.ALL,orphanRemoval=true)
Solution 3
This might also happen in (spring boot application) testing context, with the maven-surefire-plugin reuseForks set on true. The cause, in that context, are database records that are leaked between tests.
To fix the issue it is necessary to either properly clean up the test environment after running a test class, or cleanup the database test environment before running a test class.
Daniel Haughton
Updated on January 27, 2021Comments
-
Daniel Haughton over 3 years
So I have a schedule object which contains a list of DateActiveScheduleItem.I am obtaining the schedule from the database,removing a DateActiveScheuleItem from the list,and saving it using .save() from Hibernate CrudRepository.
nested exception is org.springframework.orm.jpa.JpaSystemException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: haughton.daniel.ShoutLoud.model.schedule.Schedule.dateActiveScheduleItems; nested exception is org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: haughton.daniel.ShoutLoud.model.schedule.Schedule.dateActiveScheduleItems] with root causeorg.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: haughton.daniel.ShoutLoud.model.schedule.Schedule.dateActiveScheduleItems
Schedule.java
@Entity public class Schedule { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "user_id") private User user; @ManyToOne @JoinColumn(name = "usergroup_id") private UserGroup userGroup; private String description; private boolean master;//is this a schedule for all supervalus(true) or one supervalu(false) @OneToMany(mappedBy = "schedule",cascade = CascadeType.ALL,orphanRemoval=true) private List<DateActiveScheduleItem> dateActiveScheduleItems = new ArrayList<>(); @OneToMany(mappedBy = "schedule",cascade = CascadeType.PERSIST) private List<MusicScheduleItem> musicScheduleItems = new ArrayList<>(); @OneToMany(mappedBy = "schedule",cascade = CascadeType.PERSIST) private List<AdvertisementScheduleItem> advertisementScheduleItems = new ArrayList<>(); @Basic @Temporal(TemporalType.DATE) private java.util.Date dateAdded; public Long getId() { return id; } public Date getDateAdded() { return dateAdded; } public void setDateAdded(Date dateAdded) { this.dateAdded = dateAdded; } public void setId(Long id) { this.id = id; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public UserGroup getUserGroup() { return userGroup; } public void setUserGroup(UserGroup userGroup) { this.userGroup = userGroup; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public boolean isMaster() { return master; } public void setMaster(boolean master) { this.master = master; } public List<DateActiveScheduleItem> getDateActiveScheduleItems() { return dateActiveScheduleItems; } public void setDateActiveScheduleItems(List<DateActiveScheduleItem> dateActiveScheduleItems) { this.dateActiveScheduleItems = dateActiveScheduleItems; } public List<AdvertisementScheduleItem> getAdvertisementScheduleItems() { return advertisementScheduleItems; } public void setAdvertisementScheduleItems(List<AdvertisementScheduleItem> advertisementScheduleItems) { this.advertisementScheduleItems = advertisementScheduleItems; } public List<MusicScheduleItem> getMusicScheduleItems() { return musicScheduleItems; } public void setMusicScheduleItems(List<MusicScheduleItem> musicScheduleItems) { this.musicScheduleItems = musicScheduleItems; } public boolean removeDateActiveScheduleItem(Date date){ for(int i =0;i<dateActiveScheduleItems.size();i++){ if(date.getTime()==dateActiveScheduleItems.get(i).getDate().getTime()){ dateActiveScheduleItems.remove(i); return true; } } return false; } public boolean isScheduleActiveToday(){ Calendar now = Calendar.getInstance(); for(int i=0;i<dateActiveScheduleItems.size();i++){ Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); cal1.setTime(now.getTime()); cal2.setTime(dateActiveScheduleItems.get(i).getDate()); boolean sameDay = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR); if(sameDay==true){ return true; } } return false; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Schedule schedule = (Schedule) o; if (master != schedule.master) return false; if (id != null ? !id.equals(schedule.id) : schedule.id != null) return false; if (user != null ? !user.equals(schedule.user) : schedule.user != null) return false; if (userGroup != null ? !userGroup.equals(schedule.userGroup) : schedule.userGroup != null) return false; if (description != null ? !description.equals(schedule.description) : schedule.description != null) return false; if (dateActiveScheduleItems != null ? !dateActiveScheduleItems.equals(schedule.dateActiveScheduleItems) : schedule.dateActiveScheduleItems != null) return false; if (musicScheduleItems != null ? !musicScheduleItems.equals(schedule.musicScheduleItems) : schedule.musicScheduleItems != null) return false; if (advertisementScheduleItems != null ? !advertisementScheduleItems.equals(schedule.advertisementScheduleItems) : schedule.advertisementScheduleItems != null) return false; return dateAdded != null ? dateAdded.equals(schedule.dateAdded) : schedule.dateAdded == null; } @Override public int hashCode() { int result = id != null ? id.hashCode() : 0; result = 31 * result + (user != null ? user.hashCode() : 0); result = 31 * result + (userGroup != null ? userGroup.hashCode() : 0); result = 31 * result + (description != null ? description.hashCode() : 0); result = 31 * result + (master ? 1 : 0); result = 31 * result + (dateActiveScheduleItems != null ? dateActiveScheduleItems.hashCode() : 0); result = 31 * result + (musicScheduleItems != null ? musicScheduleItems.hashCode() : 0); result = 31 * result + (advertisementScheduleItems != null ? advertisementScheduleItems.hashCode() : 0); result = 31 * result + (dateAdded != null ? dateAdded.hashCode() : 0); return result; } }
DateActiveScheduleItem
@Entity public class DateActiveScheduleItem { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Basic @Temporal(TemporalType.DATE) private Date date; public Schedule getSchedule() { return schedule; } public void setSchedule(Schedule schedule) { this.schedule = schedule; } @JsonIgnore @ManyToOne @JoinColumn(name = "schedule_id") private Schedule schedule; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DateActiveScheduleItem that = (DateActiveScheduleItem) o; if (id != null ? !id.equals(that.id) : that.id != null) return false; if (date != null ? !date.equals(that.date) : that.date != null) return false; return schedule != null ? schedule.equals(that.schedule) : that.schedule == null; } @Override public int hashCode() { int result = id != null ? id.hashCode() : 0; result = 31 * result + (date != null ? date.hashCode() : 0); result = 31 * result + (schedule != null ? schedule.hashCode() : 0); return result; } }
In my controller
This error occurs when saving any Schedule where the DateActiveScheduleItem list has anything in it
-
Daniel Haughton about 6 yearsThis seems to be relevant to me I think.So I retrieve a schedule from the database which doesnt have anything in the list,then I do schedule.setDateActiveScheduleItems(datesScheduleItems); which in my Schedule class is just this.DateActiveScheduleItems = DateActiveScheduleItems.So i should have a method which takes in a list but individually adds the items
-
Emil Hotkowski about 6 yearsYes, but also you could use schedule.getDateActiveScheduleItems.addAll(datesScheduleItems)
-
user9347049 over 3 yearsThanks mate your answer helped a lot! Can you provide more explanation as well?
-
Jp Silver almost 3 yearsWont this leave the entries in the database but just unlinked?