Hibernate无法在多个行李箱上正确操作

时间:2015-08-19 12:53:55

标签: java hibernate hibernate-onetomany

我有一个模型,它与另外两个模型有2个oneToMany关系。当我从第一个包中删除1个记录并保存对象时,休眠从第一个包中删除1个记录,这是好的,但它也删除了与第二个包中的第一个包中的记录具有相同索引的记录。我无法弄明白如何解决它。

这是我的模特

拥有者:

@Entity
@Table(name = "table_a")
public class Owner extends Serializable {

 private static final long serialVersionUID = 1L;

 @Id
 @Column(name = "id", unique = true, nullable = false)
 private int id;

 @OneToMany(mappedBy = "owner", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
 @OrderColumn(name = "position")
 private List<Dog> dogs;

 @OneToMany(mappedBy = "owner", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
 @OrderColumn(name = "position")
 private List<Cat> cats;

 public Long getId() {
    this.id;     
 }

 public void setId(Long id) {
    this.id = id;
 }

 public Dog getDogs() {
    return this.dogs;
 }

 public void setDogs(List<Dog> dogs) {
    this.dogs = dogs;
 }

 public void addDog(Dog dog) {
    dog.owner = this;
    this.dogs.add(dog);
 }

 public void removeDog(Dog dog) {
    this.dogs.remove(dog);
 }

  public Dog getCats() {
    return this.cats;
 }

 public void setCats(List<Cat> cats) {
    this.cats = cats;
 }

 public void addCat(Cat cat) {
    Cat.owner = this;
    this.cats.add(cat);
 }

 public void removeCat(Cat cat) {
    this.cats.remove(cat);
 }
}   

犬:

@Entity
@Table(name = "table_b")
public class Dog extends Serializable {

 private static final long serialVersionUID = 1L;

 @Id
 @Column(name = "id", unique = true, nullable = false)
 private int id;

 @ManyToOne
 @JoinColumn(name = "owner_id")
 private Owner owner;

 @Column(name = "position")
 private int position;

 public Long getId() {
    return this.id;
 }

 public void setId(Long id) {
    this.id = id;
 }

 public int getPosition() {
    return this.position;
 }

 public void setPosition(int index) {
    this.position = index;
 }

 public Owner getOwner() {
    return this.owner;
 }

 public void setOwner(Owner owner) {
    this.owner = owner;
 }
} 

猫:

@Entity
@Table(name = "table_c")
public class Cat extends Serializable {

 private static final long serialVersionUID = 1L;

 @Id
 @Column(name = "id", unique = true, nullable = false)
 private int id;

 @ManyToOne
 @JoinColumn(name = "owner_id")
 private Owner owner;

 @Column(name = "position")
 private int position;

 public Long getId() {
    return this.id;
 }

 public void setId(Long id) {
    this.id = id;
 }

 public int getPosition() {
    return this.position;
 }

 public void setPosition(int index) {
    this.position = index;
 }

 public Owner getOwner() {
    return this.owner;
 }

 public void setOwner(Owner owner) {
    this.owner = owner;
 }
}   

假设我们有一只拥有2只猫和2只狗的主人。

当我这样做时:

Cat cat2Remove = owner.getCats().get(1);
owner.removeCat(cat2Remove);
session.save(owner);

Hibernate从table_b中删除了第二只猫,但它也从table_c中删除了第二只狗,我想知道如何以正确的方式阻止这种情况?

3 个答案:

答案 0 :(得分:0)

由于cascade = CascadeType.ALL而发生这种情况,因此您必须删除CascadeType.ALL以了解级联的效果,请参阅this链接。

如果您只想在保存更新时级联使用cascade="save-update" 我不知道您的情况是否需要orphanRemoval = true,但请查看these个答案,看看您是否在业务中需要它。

答案 1 :(得分:0)

你需要为你的两个实体生成一个正确的equals和hashCode对。现在他们拥有完全相同的变量集(id,owner,position),可能被视为“equals” “因此他们被删除了。如果你写了一个正确的等号检查,它也检查对象类型(Eclipse可以在“Source”生成equals / hashcode菜单下为你生成这个),你的问题应该立即消失。

答案 2 :(得分:0)

正如我在评论中提到的,我认为潜在的问题是如何使用两个急切的有序集合来获取策略。因此,为了赚取时间,我建议您尝试在两个集合中添加以下Hibernate注释:

@Fetch(FetchMode.SELECT)

它告诉Hibernate应该从检索Owner实例信息的查询执行分离的选择查询来检索集合的元素。这意味着不进行连接声明。