使用hibernate进行一对一参照完整性 [英] Referential integrity with One to One using 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;
私人字符串名称;
@OneToOne(mappedBy =foo)
private FooProperties fooProperties;
}
@实体
公共类FooProperties {
@Id
私人长fp_id;
private String phoneNumber;
@OneToOne
@JoinColumn(name =foo_id,nullable = false)
private Foo foo;
$ b现在既然拥有FooProperties类,我会面临以下问题 -
如果我将FooProperties的新实例设置为Foo,则现有FooProperties仍保留在数据库中,而hibernate不会删除该实例,例如
Foo foo = entityManager.find(Foo.class,fooId);
foo.setFooProperties(new FooProperties(xxx-xxx-xxx));
entityManager.merge(foo);
结果与FooProperties表中的新行一起存在。现在我不明白我如何改变我的映射,所以我可以有上面的代码(或它的变体)适用于所有场景,这意味着我需要Foo作为拥有者和FooProperties中的foo_id。有没有办法像这样定义映射?
注意:我已经问过
在这个基础上映射这个onetoone-in-hibernate-using-jpa>问题 / code>。但是,由于解释JPA规范中的casuistics,它不会像预期的一对一关系那样工作( orphanRemoval
@Entity
public class Foo {
@OneToMany(mappedBy = foo,orphanRemoval = true)
private List< FooProperties> fooProperties;
$ b $ public FooProperties getFooProperties(){
if(fooProperties == null || fooProperties.isEmpty())return null;
else返回fooProperties.get(0);
$ b $ public void setFooProperties(FooProperties newFooProperties){
if(fooProperties == null)fooProperties = new ArrayList< FooProperties>();
else fooProperties.clear();
if(newFooProperties!= null)
fooProperties.add(newFooProperties);
}
...
}
@实体
公共类FooProperties {
@ManyToOne
@JoinColumn(name = foo_id,可为空= false)
private Foo foo;
...
}
甚至如果你不这样做需要
FooPropeties.foo
:@Entity
public class Foo {
@OneToMany(orphanRemoval = true)
@JoinColumn(name =foo_id,nullable = false)
private List< FooProperties> fooProperties;
// getter / setter as above
...
}
I'm having two tables -
Foo { foo_id, name }
Foo_properties { fp_id, foo_id, phoneNumber}
Now I want to map this in my object model using hibernate.. I need a foo_id in Foo_properties because i want to maintain referential integrity and want to add ON DELETE CASCADE constraint.
so I mapped the relation in the following way -@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; }
Now since the owning side is FooProperties class, I'm facing following issues -
If I set the new instance of FooProperties to Foo the existing FooProperties still remains in DB and hibernate doesn't delete that instance, e.g.Foo foo = entityManager.find(Foo.class, fooId); foo.setFooProperties(new FooProperties("xxx-xxx-xxx")); entityManager.merge(foo);
This results into the new row in FooProperties table along with the existing one. Now I don't understand how I can change my mapping to so I can have above code (or variant of it) working for all scenarios, that means I need Foo as a owning side and foo_id in FooProperties. Is there any way to define the mapping like this?
NOTE: I already asked question based on this but I think I wasn't clear in previous question so asked this another one.
解决方案You were already told to use
orphanRemoval = true
orCascadeType.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 ... }
这篇关于使用hibernate进行一对一参照完整性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!