Hibernate:collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance

22,518

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.

Share:
22,518
Daniel Haughton
Author by

Daniel Haughton

Updated on January 27, 2021

Comments

  • Daniel Haughton
    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
    Daniel Haughton about 6 years
    This 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
    Emil Hotkowski about 6 years
    Yes, but also you could use schedule.getDateActiveScheduleItems.addAll(datesScheduleItem‌​s)
  • user9347049
    user9347049 over 3 years
    Thanks mate your answer helped a lot! Can you provide more explanation as well?
  • Jp Silver
    Jp Silver almost 3 years
    Wont this leave the entries in the database but just unlinked?