org.hibernate.PropertyValueException: not-null property references a null or transient value
at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:103)
at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:132)
at org.hibernate.action.internal.AbstractEntityInsertAction.makeEntityManaged(AbstractEntityInsertAction.java:141)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:220)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:194)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:142)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:329)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:135)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:114)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:735)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:727)
at org.hibernate.engine.spi.CascadingAction$5.cascade(CascadingAction.java:258)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:388)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:331)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:209)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:418)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:358)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:334)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:209)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:166)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:449)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:292)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:135)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:764)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:756)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:752)
at com.lj.zhang.Student.HibernateTeam_1insert.main(HibernateTeam_1insert.java:36)
class="java"> Session session=HibernateUtil.openSession();
Team team=new Team(null,"impl_team",null);
Student s1=new Student("alleni", null);
Student s2=new Student("eline",null);
IdCard card1=new IdCard(001, s1);
IdCard card2=new IdCard(002,s2);
team.setStudents(ArraysHelper.asSet(s1,s2));
Transaction tx=session.beginTransaction();
session.save(team);
tx.commit();
package org.hibernate.engine.internal
public final class Nullability
/** Check nullability of the class persister properties
/* @param values entity properties
public void checkNullability {
...
//这里会对所有transient状态的对象进行检查,没有异常则进入下一步,最终持久化。
for ( int i = 0; i < values.length; i++ ) {
if ( checkability[i] && values[i]!= LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
final Object value = values[i];
if ( !nullability[i] && value == null ) {
//check basic level one nullablilty
throw new PropertyValueException(
"not-null property references a null or transient value",
persister.getEntityName(),
persister.getPropertyNames()[i]
);
}
else if ( value != null ) {
//values is not null and is checkable, we'll look deeper
String breakProperties = checkSubElementsNullability( propertyTypes[i], value );
if ( breakProperties != null ) {
throw new PropertyValueException(
"not-null property references a null or transient value",
persister.getEntityName(),
buildPropertyPath( persister.getPropertyNames()[i], breakProperties )
);
}
}
}
...
}
出现这个问题的原因是没有把Student应有的IdCard加进去。
Hibernate会从我们执行session.save()中的对象开始,依次将关联的对象加进session
缓存对象中。 比如这里的代码是save(team),于是会先加一个student,然后这个student对应的idcard,如此
循环递归。
但是当代码运行到Student的循环时,根据映射配置文件, 该student应该对应一个idcard,且不能为null,于是就报错了。
如下图所示,当加入了代码:
s1.setIdCard(card1);
s2.setIdCard(card2);
values[1]那里便有了该有的idcard对象地址。
之前那里为null,抛出异常。
- 大小: 117.8 KB