2017-05-23 3 views
2

私は2つのテーブルを持っている - 学生と住所を。彼らは1対1の関係を持っています。学生エンティティはアドレス実体の集合を持っています。私が学生の住所の収集を更新するとき。それはデータを更新しておらず、このエラーを出しています。子コレクションを持つ親エンティティを更新していたときに、データベース内にないキーが増分されています。 -子コレクションは、すべてカスケードで休止状態で更新されていませんか?

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

はあなたのエンティティ内のequalsとhashCodeをオーバーライドしてみデータベースにすでに存在しているIDを挿入しようと思われます。 –

+0

再生できません。あなたのファイルと設定されたhibernate.cfgをコピーしました。期待どおりに働いた。たぶん、再生のための完全なサンプルコードを共有することはできますか? –

+0

これはマッピングファイル内にあるはずですが、それ以外の場合はhibernate-mappingタグ<?xml version = "1.0"?> <!DOCTYPE hibernate-mapping PUBLIC " - // Hibernate/Hibernate Mapping DTD 3を認識します。0 // EN " " http://hibernate.org/dtd/hibernate-mapping-3.0.dtd "> –

答えて

0

"STUDENT_IDは、" あなたの主キーのいずれかに関連付けられていません。 「STUDENT_ID」は両方の学生と住所のテーブルに存在している場合は、「STUDENT_ID」と「ID」から、あなたの学生のマッピングファイルに次の行を変更:Session javadocから

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

Session.update()外れで動作するように指定されていますエンティティインスタンス"同じ識別子を持つ永続インスタンスがある場合、例外がスローされます。"まったく例外が指定されておらず、カスケードすると複雑なコードパスが送信され、このエラーが発生する可能性があります。あなたはSessionからロードすることによって、それを得たとSessionを閉じたか、それを切り離します何かを行っていないので、あなたが変更

Studentオブジェクトは、を外れではなく、むしろ永続。これは、それに対するすべての変更がSession上の任意の手動コールを必要とせず、自動的にデータベースに保存されていることを意味します。これは文で、Sessionのクラスのjavadocに指定されている「永続インスタンスへの変更は、フラッシュ時に検出され、また、SQLのUPDATEになります。」

session.update(student);の行を単に削除すると、トランザクションをコミットするときにカスケード関係で新しいアドレスを保存するなど、コードが機能し始めると思います。私は完全かどうか分からないので、私はカスケードで働いてきたので、

それはしばらくしているが、あなたはまた、関係の反対側のカスケードを設定する必要があるかもしれません。

+0

私はそれをしましたが、私はまだ同じエラーが発生します –

+0

@AmitDas両方の更新呼び出しを削除し、カスケードを追加する=アドレスマッピングファイル?それらの両方が一緒に解決しない場合は、問題を見つけるために少し実験する必要があると思う。完全なサンプルプロジェクト(githubまたはアーカイブファイルなど)を投稿すると – Douglas

+0

保存は親エンティティと子コレクションでうまくいきますが、更新のみで問題が発生しています。表示されている場合は、student_idを5としているというエラーが表示されます。がデータベースにない場合、4のstudent_idのみがデータベースにあります。 –

0

ダブルデータベーステーブルビューア/ブラウザを使用してデータベース・テーブルをチェックしてください。 あなたが(5)

+0

いいえ、それは終了しません....私はチェックした.....何が起こっている私は、親から任意の子エンティティを更新しているとき、その親は次の増分IDを取っている –

関連する問題