通过基本的一对多映射获得错误

时间:2014-09-08 16:36:51

标签: java hibernate

我正在通过遵循one-to-many unidirectional mapping

的hi​​bernate文档创建一个简单的示例

我创建了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)

请帮我解决问题。

3 个答案:

答案 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