hibernate - org.hibernate.PropertyValueException:非空属性引用空值或瞬态值
问题描述
我们任意收到了这个休眠错误
org.hibernate.PropertyValueException: not-null property references a null or transient value from production environment 但无法在本地生成。我已经给出了我们数据结构的一些伪代码和描述关系的代码。
class Parent {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "parent_id")
@OrderColumn(name = "idx")
private List<ChildA> childAs;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "parent_id")
@OrderColumn(name = "idx")
private List<ChildB> childBs;
}
class ChildB {
@NotNull
@JoinColumn(name = "child_a_id")
@ManyToOne
private ChildA childA;
}
此错误尤其发生在复制功能中,其中整个对象图从父级级联一次全部复制和持久化。</p>
void copy(Parent source) {
Parent copy = makeCopy(source);
entityManager.persist(copy);
}
Parent makeCopy(Parent source) {
Parent destination = new Parent();
// Set other properties
destination.getChildAs().addAll(
source.getChildAs()
.stream()
.map(a -> {
ChildA childA = new ChildA();
childA.setProperty(a.getProperty()); // copy properties
return childA;
})
.collect(Collectors.toList())
);
destination.getChildBs().addAll(
source.getChildBs()
.stream()
.map(b -> {
ChildB childB = new ChildB();
childB.setProperty(b.getProperty()); // copy properties
childB.setChildA(
findCopiedChildARefByUniqueProperty(
destination.getChildAs(),
b.getChildA().getUniqueProperty()
)
)
return childB;
})
.collect(Collectors.toList())
);
...
return destination;
}
它随机导致org.hibernate.PropertyValueException: not-null property references a null or transient value: ChildB.childA 在生产中运行时。
我已经检查了它在本地生成的休眠查询。为了在复制休眠时保存 ChildB 似乎总是首先插入具有空 childA 引用的 ChildB,然后插入 ChildA,然后用 childA 引用更新 childB,它在本地环境中没有任何问题。
生产错误堆栈跟踪:
org.hibernate.PropertyValueException: not-null property references a null or transient value: ChildB.childA
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:100)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:312)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:143)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:201)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:147)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:799)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:791)
at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:48)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:425)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:475)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:353)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:143)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:201)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:147)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:71)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:808)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:782)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:786)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:839)
预先感谢您的任何帮助。
笔记:
'hibernate-core' version: '3.6.10.Final'
解决方案
推荐阅读
- php - 合并多维数组(自定义)PHP - Laravel
- javascript - React - 在地图功能中表达预期
- javascript - 当mousedown直到mouseup时如何做工作?
- graphene-python - 如何以字符串的形式获取模型模式(type_defs)?
- wordpress - bot 框架中网络聊天频道上的通知
- visual-studio-code - 如何防止 VS Code 记住工作文件夹之外的文件?
- java - 如何在 Android 的 PayUMoney 支付网关中设置多种支付选项
- r - 使用 r 清理地理编码数据
- windows - 如何使用 MSYS2/MINGW64 gdb 调试使用 MSYS2/MINGW64 工具链构建但不是从 MSYS2 shell 内部构建的程序
- axapta - 如何从 InventDim 获取 InventSerialId 的计数