子集合没有更新在hibernate与cascade all?

时间:2017-05-23 15:33:45

标签: java hibernate hibernate-mapping

我有两张桌子 - 学生和地址。他们有一对多的关系。学生实体正在收集地址实体。当我更新学生的地址集合时。它没有更新数据并给出此错误。当我使用子集合更新父实体时,它接下来是增量键,而不在数据库中。 -

Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:129)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:124)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:189)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:59)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3079)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3521)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:395)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:387)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:303)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:349)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1195)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at com.HibernateExample.test.HibernateTest.main(HibernateTest.java:51)


Caused by: org.postgresql.util.PSQLException: ERROR: insert or update on table "address" violates foreign key constraint "student_fk"
  Detail: Key (id)=(5) is not present in table "student".
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2476)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2189)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:300)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:428)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:354)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:169)
    at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:136)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:186)
    ... 14 more

Student.java

public class Student {

    public int id;
    public String firstName;
    public String lastName;
    public int age;
    public Set<Address> address = new HashSet<>(0);

    public Set<Address> getAddress() {
        return address;
    }
    public void setAddress(Set<Address> address) {
        this.address = address;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

}

Address.java

public class Address {

    public int id;
    public String streetName;
    public String cityName;
    public String stateName;
    public String plotNo;
    public Student student;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getStreetName() {
        return streetName;
    }
    public void setStreetName(String streetName) {
        this.streetName = streetName;
    }
    public String getCityName() {
        return cityName;
    }
    public void setCityName(String cityName) {
        this.cityName = cityName;
    }
    public String getStateName() {
        return stateName;
    }
    public void setStateName(String stateName) {
        this.stateName = stateName;
    }
    public String getPlotNo() {
        return plotNo;
    }
    public void setPlotNo(String plotNo) {
        this.plotNo = plotNo;
    }
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }

}

HibernateTest.java

public class HibernateTest {

    public static void main(String[] args) {

        Configuration configuration = new Configuration();
        configuration.configure("hibernate-cfg.xml");
        @SuppressWarnings("deprecation")
        SessionFactory sessionFactory = configuration.buildSessionFactory();

        Session session =   sessionFactory.openSession();
        session.setFlushMode(FlushMode.COMMIT);

        System.out.println(session.getFlushMode().name());

        Transaction transaction = session.beginTransaction();

        Student  student =  (Student) session.get(Student.class, 3);


        Address address = new Address();
        address.setStateName("Kerala");
        address.setCityName("Old Delhi");
        address.setStreetName("Uttaam Nagar");
        address.setPlotNo("158A");

        address.setStudent(student);
        student.getAddress().add(address);
        session.update(student);
        transaction.commit();
        session.close();

        sessionFactory.close();

    }   
}

address.hbm.xml

<hibernate-mapping>
   <class name="com.HibernateExample.entity.Address" table="address">
      <meta attribute="class-description">
         This class contains the address detail. 
      </meta>
      <id name="id" type="int" column="id">
         <generator class="increment" />
      </id>
      <property name="streetName" column="street_name" type="string"/>
      <property name="cityName" column="city_name" type="string"/>
      <property name="stateName" column="state_name" type="string"/>
      <property name="plotNo" column="plot_no" type="string"/>

      <many-to-one name="student" class="com.HibernateExample.entity.Student" >
            <column name="student_id" not-null="true"></column>
      </many-to-one> 

   </class>
</hibernate-mapping>

student.hbm.xml

<hibernate-mapping>
   <class name="com.HibernateExample.entity.Student" table="student">
      <meta attribute="class-description">
         This class contains the student detail. 
      </meta>
      <id name="id" type="int" column="id">
         <generator class="increment" />
      </id>
      <property name="firstName" column="first_name" type="string"  length="40" />
      <property name="lastName" column="last_name" type="string" length="40" />
      <property name="age" column="age" type="int"/>

      <set name="address" cascade="all">
         <key column="student_id"/>
         <one-to-many class="com.HibernateExample.entity.Address"/>
      </set>
   </class>
</hibernate-mapping>

3 个答案:

答案 0 :(得分:2)

Session javadoc开始,Session.update()被指定用于分离的实体实例。 “如果存在具有相同标识符的持久化实例,则抛出异常。”确切地说,未指定哪个异常,并且级联可能会将其发送到复杂的代码路径,这可能会导致此错误。

您修改的Student对象不是分离,而是持久,因为您是通过从Session加载并且没有关闭了Session或做了任何会分离它的事情。这意味着对它的所有修改都会自动保存到数据库中,而无需在Session上进行任何手动调用。这在Session的类javadoc中指定,其句子“在刷新时检测到对持久化实例的更改,并导致SQL更新。”

只需删除行session.update(student);,我认为您的代码将开始工作,包括在提交事务时通过级联关系保存新地址。

自从我使用级联以来已经有一段时间了,所以我不完全确定,但你可能还需要在关系的另一端设置级联。

答案 1 :(得分:0)

“student_id”与您的任何主键都没有关联。如果学生和地址表中都存在“student_id”,则将学生映射文件中的此行从“id”更改为“student_id”:

<id name="id" type="int" column="student_id">

答案 2 :(得分:0)

使用数据库表查看器/浏览器仔细检查数据库表。 您似乎尝试插入数据库中已存在的ID(5)