简体   繁体   English

基本的一对多映射会出错

[英]Getting error with basic one-to-many mapping

I am creating a simple example by following the hibernate documentation for one-to-many unidirectional mapping 我通过遵循休眠文档进行一对多单向映射来创建一个简单的示例

I have created Person entity and Address entity as follows: 我创建了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
}

Mapping file: 映射文件:

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

My program to save person and address: 我保存人和地址的程序:

    Session session = getSession();
    session.getTransaction().begin();

    Person p = new Person();
    Address a = new Address();

    p.addAddress(a);

    session.save(a);
    session.save(p);

Executing this program is giving an exception as: not-null property references a null or transient value : Address._Person.addressesBackref 执行此程序将产生一个异常,例如: not-null property references a null or transient value : Address._Person.addressesBackref

Complete stacktrace: 完整的堆栈跟踪:

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)

Can you please help me in fixing the issue. 您能帮我解决问题吗?

At DB level, your Address table has a foreign key called personId with Person table. 在数据库级别,您的Address表具有名为personIdPerson表的外键。 Also as per the hibernate mapping file the foreign key has not-null constraint. 同样,根据休眠映射文件,外键具有not-null约束。

As per your code you are trying to save Address entity first (which goes to Address table) then you are saving the Person entity. 根据您的代码,您尝试先保存Address实体(该Address转到Address表),然后再保存Person实体。 So when hiberate tries to save the Address entity it has to insert the column personId because it has not-null constraint, as there is no record in Person table so hibernate throws an exception as Address._Person.addressesBackref . 因此,当冬眠尝试保存Address实体时,它必须插入列personId因为它具有not-null约束,因为Person表中没有记录,所以冬眠会抛出一个异常,如Address._Person.addressesBackref

So to fix this issue: 因此,要解决此问题:

Solution 1: 解决方案1:

Save the Person first then try to save the Address entity like this: 首先保存Person然后尝试保存Address实体,如下所示:

Person p = new Person();
Address a = new Address();

p.addAddress(a);

session.save(p);
session.save(a);

Solution 2 解决方案2

Just remove the not-null constraint on the foreign key - personId 只需删除外键上的not-null约束personId

Here it is clearly saying you are putting a null value for a property which is declared as a not null property. 显然,这是在为声明为非空属性的属性添加空值。

You are directly setting the objects with out any values.So person id is setting null.But you configured it as a not null.Check it once. 您直接设置没有任何值的对象,因此人员ID设置为null,但是将其配置为非null,请检查一次。

The Exception clearly explains that Address you are adding to Person.addresses is either null or transient (Not saved). 例外清楚地解释了Address要添加到Person.addresses null或暂时的(未保存)。 You can try saving Address before adding it to the Person.addresses. 您可以先尝试保存Address然后再将其添加到Person.addresses中。

And you need to commit the transaction. 并且您需要提交事务。 Please try the following code. 请尝试以下代码。

 Session session = getSession();
 Transaction tx;
 try {
     tx = session.beginTransaction();
     //do some work
     Person p = new Person();
     Address a = new Address();

     session.save(a);
     p.addAddress(a);

     session.save(p);
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     session.close();
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM