Java 子集合未在hibernate中使用cascade all进行更新?

Java 子集合未在hibernate中使用cascade all进行更新?,java,hibernate,hibernate-mapping,Java,Hibernate,Hibernate Mapping,我有两张桌子——学生和地址。他们有一对多的关系。学生实体具有地址实体的集合。当我更新学生中的地址集合时。它没有更新数据并给出此错误。当我用子集合更新父实体时,它的下一个键是不在数据库中的递增键。- Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not execute statement at org.hibernate.exception.internal.SQ

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

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

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

该类包含学生详细信息。
学生id与您的任何主键都没有关联。如果“学生id”同时存在于学生表和地址表中,则将学生映射文件中的此行从“id”更改为“学生id”:


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

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

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


我已经有一段时间没有使用cascades了,所以我不能完全确定,但是您可能还需要在关系的另一端设置cascade。

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

尝试覆盖实体中的equals和hashcode。无法复制。复制了您的文件并配置了hibernate.cfg。工作如期进行。也许你可以共享完整的复制示例代码?这应该在映射文件中,尽管在顶部,否则它如何识别hibernate映射标记@J-Alex…我如何与你共享???@AnkitGoel…它就在那里…我只是没有在这里添加它…如果没有它们,我的代码将如何识别work@AmitDas删除更新调用和是否将cascade=all添加到地址映射文件?如果这两种方法都不能解决问题,我想我需要做一些实验来找出问题所在。如果您发布了一个完整的示例项目(在github上,或者一个存档文件或其他东西上),这样我就可以确保我的设置与您的相匹配,今晚我会看一看。save可以很好地处理父实体和子集合,但只有更新会产生问题。如果您看到,错误是将数据库中没有的student_id设为5,数据库中只有student_id为4。不,它不存在……我已检查……当我从其父实体更新任何子实体时,会发生什么情况,那么其父实体将采用下一个增量id
<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>
<id name="id" type="int" column="student_id">