Hibernate: bi-directional one-to-many with one as parent
Asked Answered
B

1

5

I'm trying to setup a bi-directional one-to-many relationship with "one" as parent

I have a parent:

@Entity
public class VideoOnDemand {

   @OneToMany(cascade = CascadeType.ALL)
   @LazyCollection(LazyCollectionOption.FALSE)
   @JoinColumn(name = "video_id")
   private List<CuePoint> cuePoints = new ArrayList<CuePoint>();
}

and a child:

@Entity
public class CuePoint {

   @ManyToOne(cascade=CascadeType.ALL)
   @JoinColumn(name = "video_id", insertable = false, updatable = false)
   private VideoOnDemand video;
}

I used recommendations from the official Hibernate documentation (2.2.5.3.1.1). However, Hibernate doesn't seem to understand that CuePoint is a child entity, so, when I delete the CuePoint, it deletes VideoOnDemand as well with all the other CuePoints.

What am I doing wrong and what is the right way?

Blessington answered 9/7, 2011 at 8:36 Comment(0)
P
7

By doing that, you'be mapped a unique bidirectional association as two unidirectional associations. One of the side must be marked as the inverse of the other:

@Entity
public class VideoOnDemand {

   @OneToMany(mappedBy = "video", cascade = CascadeType.ALL)
   private List<CuePoint> cuePoints = new ArrayList<CuePoint>();
}

@Entity
public class CuePoint {

   @ManyToOne(cascade = CascadeType.ALL)
   @JoinColumn(name = "video_id", insertable = false, updatable = false)
   private VideoOnDemand video;
}

The mappedBy attribute must contain the name of the attribute of the other side of the association.

Note that this is indeed what is described at paragraph 2.2.5.3.1.1. of the documentation.

Pomfret answered 9/7, 2011 at 8:41 Comment(3)
JB, tried what you said. In this case VideoOnDemand would be a child, not a parent. In the documentation: "To map a bidirectional one to many, with the one-to-many side as the owning side, you have to remove the mappedBy element and set the many to one @JoinColumn as insertable and updatable to false." Really, when I remove the CuePoint, VideoOnDemand is still being deleted. Even more: now, when I add new CuePoint, the 'video_id' column is empty (wasn't the case before).Blessington
There is no notion of child and parent in Hibernate. There is a notion of owning side. Why do you want the one side to be the owning side? Note that the deletions in cascade that you describe in your question are simply cause by the cascade=ALL that you put on both sides of the relationship. the foreign key being null is caused by the fact that you didn't set the cuePoint's video property when adding the cuePoint to the list. You must initialize both sides of the association. And it's the owning side which is used by Hibernate to decide if the association exists.Pomfret
Yes, owning side is a key. I thought, it's about parent and child relation. Now I know what does that really mean. Ok, I just need to remove CascadeType.ALL from the CuePoint. In fact, I did set the video property in CuePoint, but the annotations were wrong. Thanks, JB!Blessington

© 2022 - 2024 — McMap. All rights reserved.