Spring/Hibernate替换一组级联对象
更新:我重写了这个问题,以尽可能地解释问题,并提供最多的信息 我有以下资料:Spring/Hibernate替换一组级联对象,hibernate,spring,replace,set,Hibernate,Spring,Replace,Set,更新:我重写了这个问题,以尽可能地解释问题,并提供最多的信息 我有以下资料: @Entity public class FooLnkBar implements java.io.Serializable { @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "SomeID", nullable = false) private Foo foo; @Man
@Entity
public class FooLnkBar implements java.io.Serializable {
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "SomeID", nullable = false)
private Foo foo;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OtherID", nullable = false)
private Bar bar;
}
@Entity
public class Foo implements java.io.Serializable {
@OneToMany(orphanRemoval=true, cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "foo")
private Set<FooLnkBar> fooLnkBars = new HashSet<FooLnkBar>(0);
}
案例2:修改一个傻瓜条并持久化一个Foo
// Load a Foo from the database and get the set of FooLnkBars
Foo foo = loadFooFromDatabase();
Set<FooLnkBar> fooLnkBars = foo.getFooLnkBars();
// Delete all existing FooLnkBar objects. Alternatively use removeAll()
Iterator<FooLnkBar> it = fooLnkBars.iterator();
while (it.hasNext()) {
FooLnkBar o = it.next();
it.remove();
}
// Add some new FooLnkBars
Foo foo = new Foo();
Bar bar = new Bar();
FooLnkBar flb = new FooLnkBar();
fooLnkBars.add(flb);
foo.setFooLnkBars(fooLnkBars);
// Save all changes
persist(foo);
案例1中的错误消息现在是“not null属性引用null或瞬态值:傻瓜吧.foo”它似乎完全按照您的指示执行: ObjectOne obj1=findInDatabase() 加载持久对象 obj1.addSet(objTwoSet) 将集合的内容添加到对象的现有集合(从而“合并”两个集合) sessionFactory.getCurrentSession().saveOrUpdate(obj1) 不必要地保存或更新()对象。对象已附加到会话,因此在提交封闭事务时,其状态将正确保持。你可以取消这一行 要清除集合中的现有内容并添加所有新内容,您应该执行以下操作:
obj1.clearSet();
obj1.addSet(objTwoSet);
更新:在Hibernate中,集合不会被视为单个离散对象。这只是一组实体,所以当你说“从数据库中删除第一个集合”时,你实际上是说“从数据库中删除第一个集合中包含的所有实体”或“将第一个集合中包含的所有实体与数据库中给定的对象断开关联”
对于前者,您将使用,并查看参考指南演示的
对于后者,您只需完全按照您正在做的操作,但如果是双向关系,您还必须正确设置另一端。因此,不是简单的:
obj1.addSet(objTwoSet);
你需要像这样的东西:
for (ObjectTwo o : obj1.getSet()) {
o.setObjectOne(null);
}
obj1.addSet(objTwoSet);
这很可能是你的问题。让对象模型处于断开状态永远都不好。它似乎完全按照您的要求执行: ObjectOne obj1=findInDatabase() 加载持久对象 obj1.addSet(objTwoSet) 将集合的内容添加到对象的现有集合(从而“合并”两个集合) sessionFactory.getCurrentSession().saveOrUpdate(obj1) 不必要地保存或更新()对象。对象已附加到会话,因此在提交封闭事务时,其状态将正确保持。你可以取消这一行 要清除集合中的现有内容并添加所有新内容,您应该执行以下操作:
obj1.clearSet();
obj1.addSet(objTwoSet);
更新:在Hibernate中,集合不会被视为单个离散对象。这只是一组实体,所以当你说“从数据库中删除第一个集合”时,你实际上是说“从数据库中删除第一个集合中包含的所有实体”或“将第一个集合中包含的所有实体与数据库中给定的对象断开关联”
对于前者,您将使用,并查看参考指南演示的
对于后者,您只需完全按照您正在做的操作,但如果是双向关系,您还必须正确设置另一端。因此,不是简单的:
obj1.addSet(objTwoSet);
你需要像这样的东西:
for (ObjectTwo o : obj1.getSet()) {
o.setObjectOne(null);
}
obj1.addSet(objTwoSet);
这很可能是你的问题。让对象模型处于断开状态永远都不好。尝试以下实现:
public class ObjectOne{
@OneToMany(cascade = CascadeType.ALL, orphanRemoval=true)
Set<ObjectTwo> obj2;
public void addSet(Set<ObjectTwo> newSet){
obj2.clear();
obj2.addAll(newSet);
}
}
公共类ObjectOne{
@OneToMany(cascade=CascadeType.ALL,orphan=true)
设置obj2;
公共无效地址集(集合新闻集){
obj2.clear();
obj2.addAll(新闻集);
}
}
关联是双向的,即ObjectTwo是否也引用ObjectOne?如果是,在清除obj2集合之前,还必须将此引用设置为null
public class ObjectOne{
@OneToMany(cascade = CascadeType.ALL, orphanRemoval=true)
Set<ObjectTwo> obj2;
public void addSet(Set<ObjectTwo> newSet){
for (ObjectTwo two : obj2) {
two.setObjectOne(null);
}
obj2.clear();
for (ObjectTwo two : newSet) {
two.setObjectOne(this);
obj2.add(two);
}
}
}
公共类ObjectOne{
@OneToMany(cascade=CascadeType.ALL,orphan=true)
设置obj2;
公共无效地址集(集合新闻集){
for(ObjectTwo:obj2){
2.setObjectOne(空);
}
obj2.clear();
for(ObjectTwo:newSet){
二、设置对象一(本);
obj2.增加(两个);
}
}
}
尝试以下实现:
public class ObjectOne{
@OneToMany(cascade = CascadeType.ALL, orphanRemoval=true)
Set<ObjectTwo> obj2;
public void addSet(Set<ObjectTwo> newSet){
obj2.clear();
obj2.addAll(newSet);
}
}
公共类ObjectOne{
@OneToMany(cascade=CascadeType.ALL,orphan=true)
设置obj2;
公共无效地址集(集合新闻集){
obj2.clear();
obj2.addAll(新闻集);
}
}
关联是双向的,即ObjectTwo是否也引用ObjectOne?如果是,在清除obj2集合之前,还必须将此引用设置为null
public class ObjectOne{
@OneToMany(cascade = CascadeType.ALL, orphanRemoval=true)
Set<ObjectTwo> obj2;
public void addSet(Set<ObjectTwo> newSet){
for (ObjectTwo two : obj2) {
two.setObjectOne(null);
}
obj2.clear();
for (ObjectTwo two : newSet) {
two.setObjectOne(this);
obj2.add(two);
}
}
}
公共类ObjectOne{
@OneToMany(cascade=CascadeType.ALL,orphan=true)
设置obj2;
公共无效地址集(集合新闻集){
for(ObjectTwo:obj2){
2.setObjectOne(空);
}
obj2.clear();
for(ObjectTwo:newSet){
二、设置对象一(本);
obj2.增加(两个);
}
}
}
addSetmethod到底做什么?在本例中,它是一个虚拟方法,可以向ObjectOne添加一组ObjectTwo。您可以向我们展示您的xml映射代码吗?或者注释配置?我已经为Object2设置了(cascade=CascadeType.ALL)。我是否应该使用另一种替代而不是合并的方法?您是否尝试过将DELETE-ORPHAN
与ALL
一起使用?addSet
方法到底是做什么的?在本例中,它是一个虚拟方法,可以向ObjectOne添加一组ObjectTwo。您可以向我们展示您的xml映射代码吗?或者注释配置?我已经为Object2设置了(cascade=CascadeType.ALL)。我是否应该使用另一种替代而不是合并的方法?您是否尝试过将DELETE-ORPHAN
与ALL
一起使用?此外,如果我必须调用clearSet方法,然后调用另一个方法来添加新的集合,那么我必须撤回现有集合并手动比较它们,以查看是否有差异。换句话说,我不想清除然后重新添加相同的集合。我假设hibernate有一些方法可以自动为您完成所有这一切?我正在尝试后一种方法。谢谢你的建议,很有意义!我很快会尝试一下,看看这是否能解决问题。结果证明它不起作用。我不能设置另一个