Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 337
Daniel Haughton Avatar asked Apr 27 '18 08:04

Daniel Haughton


People also ask

What is Cascade all Delete orphan in hibernate?

all-delete-orphan - when an object is save/update/delete, check the associations and save/update/delete all the objects found. In additional to that, when an object is removed from the association and not associated with another object (orphaned), also delete it.

Is orphanRemoval true?

If orphanRemoval=true is specified the disconnected Address instance is automatically removed. This is useful for cleaning up dependent objects (e.g. Address ) that should not exist without a reference from an owner object (e.g. Employee ).

What is orphanRemoval?

When a target entity in one-to-one or one-to-many relationship is removed from the relationship, it is often desirable to cascade the remove operation to the target entity. Such target entities are considered “orphans,” and the orphanRemoval attribute can be used to specify that orphaned entities should be removed.

What is cascade type all?

The meaning of CascadeType. ALL is that the persistence will propagate (cascade) all EntityManager operations ( PERSIST, REMOVE, REFRESH, MERGE, DETACH ) to the relating entities. It seems in your case to be a bad idea, as removing an Address would lead to removing the related User .


3 Answers

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.

like image 153
Emil Hotkowski Avatar answered Oct 17 '22 20:10

Emil Hotkowski


Rempove orphanRemoval=true from here.

@OneToMany(mappedBy = "schedule",cascade = CascadeType.ALL,orphanRemoval=true)
like image 43
Shubham Avatar answered Oct 17 '22 21:10

Shubham


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.

like image 1
razvanone Avatar answered Oct 17 '22 20:10

razvanone