Hibernate奇怪的行为。多对多。删除时级联ALL

时间:2016-11-25 10:28:35

标签: hibernate many-to-many cascade cascading-deletes

我有以下型号:

廊-照片的关键字
|
关键字

@Entity
@Table(name = "galleries")
public class Gallery extends BaseModel{       

  @OneToMany(cascade = PERSIST, mappedBy = "mainGallery", orphanRemoval = true)
  public List<Photo> photos;

  @ManyToMany(fetch = LAZY, cascade = ALL)
  @JoinTable(name="gallery_keywords", joinColumns=    {@JoinColumn(name="gallery_id")}, inverseJoinColumns={@JoinColumn(name="keyword_id")})
  public List<Keyword> keywords = new ArrayList<>();


@Entity
@Table(name = "photos")
public class Photo extends BaseModel{

  @ManyToOne(fetch = LAZY, cascade = PERSIST) public Gallery mainGallery;

  @ManyToMany(fetch = LAZY, cascade = ALL)
  @JoinTable(name="photo_keywords", joinColumns= {@JoinColumn(name="photo_id")}, inverseJoinColumns={@JoinColumn(name="keyword_id")})
  public List<Keyword> keywords = new ArrayList<>();

@Entity
@Table(name = "keywords")
public class Keyword extends BaseModel {

  @ManyToMany(fetch = LAZY)
  @JoinTable(name="photo_keywords", joinColumns={@JoinColumn(name="keyword_id")}, inverseJoinColumns={@JoinColumn(name="photo_id")})
  public List<Photo> photos = new ArrayList<>();

  @ManyToMany(fetch = LAZY)
  @JoinTable(name="gallery_keywords", joinColumns={@JoinColumn(name="keyword_id")}, inverseJoinColumns={@JoinColumn(name="gallery_id")})
  public List<Gallery> galleries = new ArrayList<>();

问题:我在删除照片时遇到问题 如果属于此照片的任何关键字未出现在此图库的任何其他照片中,则会从数据库中删除它,尽管它在photo_keywords表中有记录并且属于其他图库中的其他照片。

但如果关键字属于此图库的其他照片,则不会被删除。

删除代码:

public void delete(Photo photo) {
  photo.mainGallery.photos.remove(photo);
  photo.delete();
}

从关键字字段注释中的Photo类中删除 cascade = ALL 解决它。但还为什么呢?

1 个答案:

答案 0 :(得分:0)

Thnx to @JB Nizet。

问题在于双方都有拥有和反向注释。这就是为什么cascade被忽略了。 但是在文档中,据说双向关联具有拥有方和反向(mappedBy)方。 这就是行为无法预测的原因。 从关键字中删除不必要的注释:

@JoinTable(name="photo_keywords", joinColumns={@JoinColumn(name="keyword_id")}, inverseJoinColumns={@JoinColumn(name="photo_id")})

并补充说:mappedBy = "keywords" 我开始得到合理的例外: org.hibernate.exception.ConstraintViolationException: could not execute statement 所以我用cascade = {PERSIST,MERGE}取代了cascade = ALL

就是这样。