Referential integrity with One to One using hibernate

こ雲淡風輕ζ 提交于 2019-12-01 20:51:43

You were already told to use orphanRemoval = true or CascadeType.DELETE_ORPHAN. However, due to casuistics in interpretation of JPA Specification it wouldn't work as expected for one-to-one relationships (HHH-5559).

You can achieve a proper behaviour of orphanRemoval with the following trick:

@Entity
public class Foo{
    @OneToMany(mappedBy = "foo", orphanRemoval = true)
    private List<FooProperties> fooProperties;

    public FooProperties getFooProperties() {
        if (fooProperties == null || fooProperties.isEmpty()) return null;
        else return fooProperties.get(0);
    }

    public void setFooProperties(FooProperties newFooProperties) {
        if (fooProperties == null) fooProperties = new ArrayList<FooProperties>();
        else fooProperties.clear();
        if (newFooProperties != null)
            fooProperties.add(newFooProperties);            
    }
    ...
}

@Entity
public class FooProperties{
    @ManyToOne
    @JoinColumn(name = "foo_id",  nullable = false)
    private Foo foo;
    ...
}

Or even this, if you don't need FooPropeties.foo:

@Entity
public class Foo{
    @OneToMany(orphanRemoval = true)
    @JoinColumn(name = "foo_id",  nullable = false)        
    private List<FooProperties> fooProperties;

    // getter/setter as above
    ...
}

I think instead of calling merge on the entity, if you directly call update on session object then hibernate will first delete the existing row and then it will add the new one. I implemented the same, but, in my case I used xml for mapping the entity. I hope this will help you.

Bar is the owner of the association (as indicated by the mappedBy on the inverse side) and thus the cascade has to be set there.

Edit:

To invert that, this might help.

There are 2 options for you to choose from, since you don't want to change your mapping :

  1. Do it via your service layer logic. I think you have a similar question already.
  2. Use the Hibernate annotation @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) on the Foo side of the relationship. However this is explicitly Hibenate and JPA 2 doesn't include support for the same.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!