2017-05-23 2 views
2

Ich habe zwei Tabellen - Student und Adresse. Sie haben eine Beziehung zu einander. Die Schülerentität hat eine Sammlung von Adreßentitäten. Wenn ich die Sammlung der Adresse im Studenten aktualisiere. Es aktualisiert die Daten nicht und gibt diesen Fehler aus. Als ich die übergeordnete Entität mit der Kindersammlung aktualisiert habe, wird als nächstes der inkrementierte Schlüssel genommen, der nicht in der Datenbank ist. -Kindersammlung wird nicht im Winterschlaf mit Kaskade alle aktualisiert?

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

Versuchen Sie, überschreiben und Hashcode in Ihren Entitäten. –

+0

Kann nicht reproduziert werden. Kopierte Ihre Dateien + konfiguriert hibernate.cfg. Hat wie erwartet funktioniert. Vielleicht können Sie den vollständigen Beispielcode für die Reproduktion freigeben? –

+0

Dies sollte in den Mapping-Dateien jedoch oben sein, sonst erkennt es das Hibernate-Mapping-Tag

Antwort

0

Die "STUDENT_ID" wird mit jedem Ihrer Primärschlüssel nicht verbunden. Wenn „STUDENT_ID“ existiert in beiden Studenten und Adresstabellen dann diese Zeile in Ihrer Datei Schüler-Mapping ändern von „id“ auf „STUDENT_ID“:

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

Vom Session javadoc wird Session.update() angegeben mit einem freistehend arbeiten Entitätsinstanz. "Wenn eine persistente Instanz mit demselben Bezeichner existiert, wird eine Ausnahme ausgelöst." Genau die Ausnahme, die nicht angegeben wurde, und die Kaskadierung könnte einen komplexen Codepfad senden, der zu diesem Fehler führen könnte.

Das Student Objekt ändern Sie ist nicht abgelöst, sondern persistent, denn Sie haben es von der Session Laden und haben nicht die Session oder getan etwas anderes geschlossen, die es lösen würde. Dies bedeutet, dass alle Änderungen automatisch in der Datenbank gespeichert werden, ohne dass ein manueller Anruf unter Session erforderlich ist. Dies wird in der Klasse javadoc für Session mit dem Satz "Änderungen an persistenten Instanzen werden zur Sperrzeit erkannt und führen auch zu einem SQL UPDATE."

Löschen Sie einfach die Zeile session.update(student);, und ich denke, dass Ihr Code zu arbeiten beginnt, einschließlich der neuen Adresse durch die kaskadierte Beziehung speichern, wenn Sie die Transaktion festschreiben.

Es ist eine Weile her, seit ich mit Kaskaden gearbeitet habe, also bin ich mir nicht ganz sicher, aber Sie müssen möglicherweise auch Kaskade auf der anderen Seite der Beziehung setzen.

+0

ich habe das, aber ich bekomme immer noch den gleichen Fehler –

+0

@AmitDas Sowohl Entfernen der Update-Aufruf und Hinzufügen von Kaskade = alle auf die Adress Mapping-Datei? Wenn beide zusammen nicht lösen, ich denke, ich müsste etwas experimentieren, um das Problem zu finden.Wenn Sie ein komplettes Beispiel-Projekt (auf Github, oder eine Archivdatei oder etwas), also ich kann sicher sein, dass mein Setup zu Ihrem passt, ich werde heute Abend einen Blick darauf werfen – Douglas

+0

Speichern funktioniert gut mit Parent-Entity und Child-Auflistung, aber nur Update erstellt Problem. Wenn Sie sehen, der Fehler sagt, dass Student_id als 5 nimmt ist nicht in der Datenbank, nur student_id mit 4 ist in der Datenbank. –

0

Überprüfen Sie Ihre Datenbanktabelle mit einem Datenbanktabellen-Viewer/Browser. Es scheint, dass Sie versuchen, eine ID einzufügen, die bereits in der Datenbank vorhanden ist (5)

+0

nein es geht nicht .... ich habe überprüft ..... was passiert, wenn ich eine untergeordnete Entität von ihrem Elternteil aktualisiere, dann nimmt ihr Elternteil die nächste Inkrement-ID –

Verwandte Themen