我正在通过遵循one-to-many unidirectional mapping
的hibernate文档创建一个简单的示例我创建了Person
实体和Address
实体,如下所示:
Person.java
public class Person {
private int id;
private Set<Address> addresses = new HashSet<Address>();
// Setters & Getters
public void addAddress(Address address) {
this.addresses.add(address);
}
}
Address.java
public class Address {
private int id;
// Setters & Getters
}
映射文件:
<hibernate-mapping>
<class name="Person">
<id name="id" column="personId">
<generator class="native" />
</id>
<set name="addresses">
<key column="personId" not-null="true" />
<one-to-many class="Address" />
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native" />
</id>
</class>
</hibernate-mapping>
我保存人员和地址的程序:
Session session = getSession();
session.getTransaction().begin();
Person p = new Person();
Address a = new Address();
p.addAddress(a);
session.save(a);
session.save(p);
执行此程序的例外情况为:not-null property references a null or transient value : Address._Person.addressesBackref
完成堆栈跟踪:
org.hibernate.PropertyValueException: not-null property references a null or transient value : Address._Person.addressesBackref
at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:106)
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:201)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:179)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:166)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:332)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:137)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
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:715)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
请帮我解决问题。
答案 0 :(得分:1)
在数据库级别,您的Address
表有一个名为personId
的外键,其中包含Person
表。另外,根据hibernate映射文件,外键具有not-null
约束。
根据您的代码,您首先尝试保存Address
实体(转到Address
表),然后保存Person
实体。因此,当hiberate尝试保存Address
实体时,它必须插入列personId
,因为它具有not-null
约束,因为Person
表中没有记录所以hibernate会抛出例外Address._Person.addressesBackref
。
所以要解决这个问题:
解决方案1:
首先保存Person
然后尝试保存Address
实体,如下所示:
Person p = new Person();
Address a = new Address();
p.addAddress(a);
session.save(p);
session.save(a);
解决方案2
只需删除外键上的not-null
约束 - personId
答案 1 :(得分:1)
这里显然是说你为一个声明为非null属性的属性设置了一个空值。
您正在直接设置没有任何值的对象。因此,人员ID设置为null。但您将其配置为非null。请检查一次。
答案 2 :(得分:0)
异常清楚地解释了您要添加到Address
的{{1}}为空或暂时(未保存)。在将其添加到Person.addresses之前,您可以尝试保存Person.addresses
。
您需要提交交易。请尝试以下代码。
Address