JavaEE TreeSet 导致 org.hibernate.TransientPropertyValueException
JavaEE TreeSet causes org.hibernate.TransientPropertyValueException
我有一个ClassA。A有一个B的TreeSet。B有一个C的TreeSet。C有一个D的HashSet。
我遇到了这个异常:
Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : D.c -> C
我明白为什么我通常会得到那个异常。但是在这种情况下我真的无法想象为什么,因为当我将 B.cSortedSet 的类型更改为普通设置时它会起作用。有人有想法吗?
Class可读性更好的文档可以在这里找到:
@Entity
public class A extends SortableEntity {
@OneToMany(mappedBy = „a“, cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
@OrderBy("sortOrder")
public SortedSet<B> bSortedSet = new TreeSet<>();
}
@Entity
public class B extends SortableEntity {
@OneToMany(mappedBy = „b“, cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
@OrderBy("sortOrder")
public SortedSet<C> cSortedSet = new TreeSet<>(); // Wont work.
// public Set<C> cSet = new HashSet<>(); // Will work.
@ManyToOne
public A a;
}
@Entity
public class C extends SortableEntity {
@OneToMany(mappedBy = „c“, cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
public Set<D> dSet = new HashSet<>();
@ManyToOne
public B b;
}
@Entity
public class D {
@ManyToOne
public C c;
}
@MappedSuperClass
public abstract class D {
@ManyToOne
public Integer sortOrder;
}
注意:通常属性都是私有的,它们有getters和setters。实现了 Comparable 并覆盖了 equal 方法。
编辑:
Anil 的回答是正确的。这似乎是问题所在,当树集重新排列它的元素时,它正在破坏反向引用,它们需要再次持久化。这只是我最好的想法。我没有证据证明这一点,但是通过操纵数据(这样集合就不必自行排序),我可以让它工作。
当您的实体中有一个集合,并且该集合包含一个或多个数据库中不存在的项目时,就会发生这种情况。
对于上面的代码,它与 @ManyToOne 的 CASCADE 属性 有关
使用cascade=CascadeType.PERSIST,测试结果
我有一个ClassA。A有一个B的TreeSet。B有一个C的TreeSet。C有一个D的HashSet。
我遇到了这个异常:
Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : D.c -> C
我明白为什么我通常会得到那个异常。但是在这种情况下我真的无法想象为什么,因为当我将 B.cSortedSet 的类型更改为普通设置时它会起作用。有人有想法吗?
Class可读性更好的文档可以在这里找到:
@Entity
public class A extends SortableEntity {
@OneToMany(mappedBy = „a“, cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
@OrderBy("sortOrder")
public SortedSet<B> bSortedSet = new TreeSet<>();
}
@Entity
public class B extends SortableEntity {
@OneToMany(mappedBy = „b“, cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
@OrderBy("sortOrder")
public SortedSet<C> cSortedSet = new TreeSet<>(); // Wont work.
// public Set<C> cSet = new HashSet<>(); // Will work.
@ManyToOne
public A a;
}
@Entity
public class C extends SortableEntity {
@OneToMany(mappedBy = „c“, cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
public Set<D> dSet = new HashSet<>();
@ManyToOne
public B b;
}
@Entity
public class D {
@ManyToOne
public C c;
}
@MappedSuperClass
public abstract class D {
@ManyToOne
public Integer sortOrder;
}
注意:通常属性都是私有的,它们有getters和setters。实现了 Comparable 并覆盖了 equal 方法。
编辑:
Anil 的回答是正确的。这似乎是问题所在,当树集重新排列它的元素时,它正在破坏反向引用,它们需要再次持久化。这只是我最好的想法。我没有证据证明这一点,但是通过操纵数据(这样集合就不必自行排序),我可以让它工作。
当您的实体中有一个集合,并且该集合包含一个或多个数据库中不存在的项目时,就会发生这种情况。
对于上面的代码,它与 @ManyToOne 的 CASCADE 属性 有关 使用cascade=CascadeType.PERSIST,测试结果