Hibernate异常org.hibernate.PropertyValueException:not-null属性引用null或transient值

时间:2015-03-13 13:18:21

标签: java hibernate exception properties

您好我正在开发小应用程序来练习hibernate。我试图做一对多的关系而且我被卡住了。

我有2个课程问答:

package com.sample;

import java.util.List;

public class Question {
    private int id;
    private String qname;
    private List<Answer> answers;

    public Question() {

    }

    public Question(int id, String qname, List<Answer> answers) {
        super();
        this.id = id;
        this.qname = qname;
        this.answers = answers;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getQname() {
        return qname;
    }

    public void setQname(String qname) {
        this.qname = qname;
    }

    public List<Answer> getAnswers() {
        return answers;
    }

    public void setAnswers(List<Answer> answers) {
        this.answers = answers;
    }

}

package com.sample;

public class Answer {
    private int id;
    private String answername;
    private String postedBy;
    private Question question;

    public Answer() {

    }

    public Answer(int id, String answername, String postedBy, Question question) {
        super();
        this.id = id;
        this.answername = answername;
        this.postedBy = postedBy;
        this.question = question;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAnswername() {
        return answername;
    }

    public void setAnswername(String answername) {
        this.answername = answername;
    }

    public String getPostedBy() {
        return postedBy;
    }

    public void setPostedBy(String postedBy) {
        this.postedBy = postedBy;
    }

    public Question getQuestion() {
        return question;
    }

    public void setQuestion(Question question) {
        this.question = question;
    }


}

配置文件如下:

question.hbm.xml:

<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-mapping PUBLIC  
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.sample.Question" table="question">
        <id name="id">
            <generator class="increment"></generator>
        </id>
        <property name="qname"></property>

        <bag name="answers" table="answer" inverse="true" lazy="true"
            fetch="select" cascade="all">
            <key>
                <column name="question_id" not-null="true">
                </column>
            </key>
            <one-to-many class="com.sample.Answer"></one-to-many>
        </bag>

    </class>

</hibernate-mapping>

answer.hbm.xml:

<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-mapping PUBLIC  
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.sample.Answer" table="answer">
        <id name="id">
            <generator class="increment"></generator>
        </id>
        <property name="answername"></property>
        <property name="postedBy"></property>
        <many-to-one name="question" class="com.sample.Question"
            fetch="select">
            <column name="question_id" not-null="true">
            </column>
        </many-to-one>
    </class>

</hibernate-mapping>

我的主文件如下:

import java.util.ArrayList;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class StoreData {
    public static void main(String[] args) {
        Session session = SessionFactoryUtil.getSessionFactory()
                .getCurrentSession();
        Transaction t = session.beginTransaction();

        Answer ans1 = new Answer();
        ans1.setAnswername("java is a programming language");
        ans1.setPostedBy("Ravi Malik");

        Answer ans2 = new Answer();
        ans2.setAnswername("java is a platform");
        ans2.setPostedBy("Sudhir Kumar");

        Answer ans3 = new Answer();
        ans3.setAnswername("Servlet is an Interface");
        ans3.setPostedBy("Jai Kumar");

        Answer ans4 = new Answer();
        ans4.setAnswername("Servlet is an API");
        ans4.setPostedBy("Arun");

        ArrayList<Answer> list1 = new ArrayList<Answer>();
        list1.add(ans1);
        list1.add(ans2);

        ArrayList<Answer> list2 = new ArrayList<Answer>();
        list2.add(ans3);
        list2.add(ans4);

        Question question1 = new Question();
        question1.setQname("What is Java?");
        question1.setAnswers(list1);

        Question question2 = new Question();
        question2.setQname("What is Servlet?");
        question2.setAnswers(list2);

        session.persist(question1);
        session.persist(question2);

        t.commit();
//      session.close();
        System.out.println("success");

    }
}

当我运行应用程序时,我收到以下错误:

Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value : com.sample.Answer.question
    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:203)
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:181)
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:168)
    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.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
    at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:314)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:460)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:294)
    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.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:356)
    at com.sun.proxy.$Proxy0.persist(Unknown Source)
    at com.sample.StoreData.main(StoreData.java:46)

2 个答案:

答案 0 :(得分:0)

Hibernate尝试保存答案,该答案引用了在保存时没有id的问题。

首先尝试保存没有答案的问题,然后为每个答案调用setQuestion传递已保存的问题。只需保存答案。

答案 1 :(得分:0)

我通过先添加问题然后将问题设置为答案来修复它。

    Question question1 = new Question();
    question1.setQname("What is Java?");

    Question question2 = new Question();
    question2.setQname("What is Servlet?");

    session.persist(question1);
    session.persist(question2);

    Answer ans1 = new Answer();
    ans1.setAnswername("java is a programming language");
    ans1.setPostedBy("Ravi Malik");
    ans1.setQuestion(question1);

    Answer ans2 = new Answer();
    ans2.setAnswername("java is a platform");
    ans2.setPostedBy("Sudhir Kumar");
    ans2.setQuestion(question1);

    Answer ans3 = new Answer();
    ans3.setAnswername("Servlet is an Interface");
    ans3.setPostedBy("Jai Kumar");
    ans3.setQuestion(question2);

    Answer ans4 = new Answer();
    ans4.setAnswername("Servlet is an API");
    ans4.setPostedBy("Arun");
    ans4.setQuestion(question2);

    session.persist(ans1);
    session.persist(ans2);
    session.persist(ans3);
    session.persist(ans4);