使用hibernate一对一引用完整性
我有两张桌子 –
Foo {foo_id,name}
Foo_properties {fp_id,foo_id,phoneNumber}
现在我想使用hibernate在我的对象模型中映射它。我需要在Foo_properties中使用foo_id,因为我想保持参照完整性并希望添加ON DELETE CASCADE约束。
所以我用以下方式映射关系 –
@Entity public class Foo{ @Id private long foo_id; private String name; @OneToOne(mappedBy = "foo") private FooProperties fooProperties; } @Entity public class FooProperties{ @Id private long fp_id; private String phoneNumber; @OneToOne @JoinColumn(name = "foo_id", nullable = false) private Foo foo; }
既然拥有方是FooProperties类,我面临以下问题 –
如果我将FooProperties的新实例设置为Foo,则现有的FooProperties仍然保留在DB中,而hibernate不会删除该实例,例如
Foo foo = entityManager.find(Foo.class, fooId); foo.setFooProperties(new FooProperties("xxx-xxx-xxx")); entityManager.merge(foo);
这导致FooProperties表中的新行以及现有行。 现在我不明白我如何改变我的映射,所以我可以让上面的代码(或它的变体)适用于所有场景,这意味着我需要Foo作为拥有方和FooProperties中的foo_id。 有没有办法像这样定义映射?
注意:我已经根据这个问题提出了问题 ,但我认为我在上一个问题中并不清楚,所以又问了另一个问题。
您已被告知使用orphanRemoval = true
或CascadeType.DELETE_ORPHAN
。 但是,由于对JPA规范的解释具有欺骗性,因此对于一对一的关系( HHH-5559 )不会如预期的那样起作用。
您可以使用以下技巧实现orphanRemoval
的正确行为:
@Entity public class Foo{ @OneToMany(mappedBy = "foo", orphanRemoval = true) private List 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 (); else fooProperties.clear(); if (newFooProperties != null) fooProperties.add(newFooProperties); } ... } @Entity public class FooProperties{ @ManyToOne @JoinColumn(name = "foo_id", nullable = false) private Foo foo; ... }
或者甚至是这个,如果你不需要FooPropeties.foo
:
@Entity public class Foo{ @OneToMany(orphanRemoval = true) @JoinColumn(name = "foo_id", nullable = false) private List fooProperties; // getter/setter as above ... }
我认为不是在实体上调用merge,如果直接调用session对象上的update,那么hibernate将首先删除现有的行,然后它将添加新的行。 我实现了相同的,但在我的情况下,我使用xml映射实体。 我希望这能帮到您。
Bar
是关联的所有者(由反面的mappedBy
表示),因此必须在那里设置级联。
编辑:
要反过来, 这可能会有所帮助。
有两个选项供您选择,因为您不想更改映射:
- 通过您的服务层逻辑来完成。 我想你已经有了类似的问题。
- 在关系的Foo端使用Hibernate注释@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)。 然而,这是明确的Hibenate和JPA 2不包括对相同的支持。
- 一个JPQL查询中的多个连接提取
- Spring boot + Hibernate + JPA没有事务性的EntityManager可用
- 在执行JPA查询时获取NoSuchMethodError:javax.persistence.Table.indexes()
- Hibernate回调
- 重写持久化实体的hashCode()和equals()方法的正确方法是什么?
- Hibernate使用PostgreSQL序列不会影响序列表
- 引起:java.io.FileNotFoundException:无法打开ServletContext资源
- 保存新对象时,Hibernate未知实体错误
- 支持实体 – 属性 – 值模型的Java框架