Hello,
I have a question of mapping tables together
My table structure is as the following diagramm shows:
I want to add topo_reports to existing items in the table tbl_imported_geometries. One entry in the table tbl_topo_report belongs to exactly one item in the table tbl_topo_kat.
I think I have made a mistake somewhere in the mapping files.
Here are my POJOs for the tables (getter- and setter omitted here):
ImportedGeometries .java
Code:
package com.mycompany.geomanagement.dao.transferobjects;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class ImportedGeometries {
private Long id;
// name of the referenced geometry table in the db
private String name;
private String version;
private Date importDate;
private Timestamp importTime;
private Vendor vendor;
private User user;
private Country country;
private Statistic statistic;
private Set reports = new HashSet();
}
TopoKat.java
Code:
package com.mycompany.geomanagement.dao.transferobjects;
import java.util.Set;
public class TopoKat {
private Long id;
private String katName;
private String katDescription;
private Set reports;
TopoReport.java
Code:
package com.mycompany.geomanagement.dao.transferobjects;
public class TopoReport {
private Long id;
private String warningMsg;
And here the mapping files:
ImportedGeometries.hbm.xml
Code:
<?xml version="1.0"?>
<!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.mycompany.geomanagement.dao.transferobjects.ImportedGeometries" table="tbl_imported_geometries" lazy="false">
<id name="id" type="java.lang.Long">
<column name="id_imported_geometries" />
<generator class="native"/>
</id>
<property name="name">
<column name="name" />
</property>
<property name="version">
<column name="version" />
</property>
<property name="importDate">
<column name="import_date" />
</property>
<property name="importTime">
<column name="import_time" />
</property>
<many-to-one name="vendor" class="com.mycompany.geomanagement.dao.transferobjects.Vendor" cascade="all" unique="true" column="fk_vendor"/>
<many-to-one name="user" class="com.mycompany.geomanagement.dao.transferobjects.User" cascade="all" unique="true" column="fk_user"/>
<many-to-one name="country" class="com.mycompany.geomanagement.dao.transferobjects.Country" cascade="all" unique="true" column="fk_country"/>
<many-to-one name="statistic" class="com.mycompany.geomanagement.dao.transferobjects.Statistic" cascade="all" unique="true" column="fk_statistic"/>
<set name="reports" cascade="all" lazy="false">
<key column="fk_imported_geometries"/>
<one-to-many class="com.mycompany.geomanagement.dao.transferobjects.TopoReport"/>
</set>
</class>
</hibernate-mapping>
TopoKat.hbm.xml
Code:
<?xml version="1.0"?>
<!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.mycompany.geomanagement.dao.transferobjects.TopoKat" table="tbl_topo_kat" lazy="false">
<id name="id" type="java.lang.Long">
<column name="id_topo_kat" />
<generator class="native"/>
</id>
<property name="katName">
<column name="kat_name" />
</property>
<property name="katDescription">
<column name="kat_description" />
</property>
<set name="reports" cascade="all" lazy="false">
<key column="fk_imported_geometries"/>
<one-to-many class="com.mycompany.geomanagement.dao.transferobjects.TopoReport"/>
</set>
</class>
</hibernate-mapping>
TopoReport.hbm.xml
Code:
<?xml version="1.0"?>
<!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.mycompany.geomanagement.dao.transferobjects.TopoReport" table="tbl_topo_report" lazy="false">
<id name="id" type="java.lang.Long">
<column name="id_topo_report" />
<generator class="native"/>
</id>
<property name="warningMsg">
<column name="warning_msg" />
</property>
</class>
</hibernate-mapping>
When I run the following code, I get an error:
Code:
public void saveReportsToExistingImpoertedGeometries() {
// Create new reports
ITopoReportDAO reportDAO = postgresqlFactory.getTopoReportDAO();
TopoReport report1 = new TopoReport();
report1.setWarningMsg("MSG5");
TopoReport report2 = new TopoReport();
report2.setWarningMsg("MSG6");
HashSet reports = new HashSet();
reports.add(report1);
reports.add(report2);
// Get existing topo_kat
ITopoKatDAO katDAO = postgresqlFactory.getTopoKatDAO();
TopoKat kat = katDAO.getTopokatByID(new Long(3));
kat.setReports(reports);
// get existing country
ICountryDAO countryDAO = postgresqlFactory.getCountryDAO();
Country country = countryDAO.getCountryByID(new Long(295));
// get existing geometry
IImportedGeometriesDAO importedGeometriesDAO = postgresqlFactory.getImportedGeometriesDAO();
ImportedGeometries importedGeometries = importedGeometriesDAO.getImportedGeometries("xxxa", "2006", country);
// add reports to the existing geometry
importedGeometries.setReports(reports);
// Update geometry
importedGeometriesDAO.changeImportedGeometries(importedGeometries);
// update category
katDAO.changeTopoKat(kat);
}
Here is the error message:
Code:
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.mycompany.geomanagement.dao.TopoKatDAOImpl.changeTopoKat(TopoKatDAOImpl.java:67)
at tests.DAOTest.saveReportsToExistingImpoertedGeometries(DAOTest.java:208)
at tests.DAOTest.main(DAOTest.java:263)
Caused by: java.sql.BatchUpdateException: Batch-Eintrag 0 update tbl_topo_report set fk_imported_geometries=3 where id_topo_report=329 wurde abgebrochen. Rufen Sie 'getNextException' auf, um die Ursache zu erfahren.
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2530)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2592)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
... 10 more
13:50:46,431 DEBUG AbstractBatcher:366 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
13:50:46,431 DEBUG AbstractBatcher:525 - closing statement
13:50:46,431 DEBUG JDBCExceptionReporter:69 - Could not execute JDBC batch update [update tbl_topo_report set fk_imported_geometries=? where id_topo_report=?]
java.sql.BatchUpdateException: Batch-Eintrag 0 update tbl_topo_report set fk_imported_geometries=3 where id_topo_report=329 wurde abgebrochen. Rufen Sie 'getNextException' auf, um die Ursache zu erfahren.
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2530)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2592)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.mycompany.geomanagement.dao.TopoKatDAOImpl.changeTopoKat(TopoKatDAOImpl.java:67)
at tests.DAOTest.saveReportsToExistingImpoertedGeometries(DAOTest.java:208)
at tests.DAOTest.main(DAOTest.java:263)
13:50:46,521 WARN JDBCExceptionReporter:77 - SQL Error: 0, SQLState: null
13:50:46,521 ERROR JDBCExceptionReporter:78 - Batch-Eintrag 0 update tbl_topo_report set fk_imported_geometries=3 where id_topo_report=329 wurde abgebrochen. Rufen Sie 'getNextException' auf, um die Ursache zu erfahren.
13:50:46,521 WARN JDBCExceptionReporter:77 - SQL Error: 0, SQLState: 23503
13:50:46,521 ERROR JDBCExceptionReporter:78 - ERROR: insert or update on table "tbl_topo_report" violates foreign key constraint "fki_imported_geometries"
Detail: Key (fk_imported_geometries)=(3) is not present in table "tbl_imported_geometries".
13:50:46,521 ERROR AbstractFlushingEventListener:301 - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.mycompany.geomanagement.dao.TopoKatDAOImpl.changeTopoKat(TopoKatDAOImpl.java:67)
at tests.DAOTest.saveReportsToExistingImpoertedGeometries(DAOTest.java:208)
at tests.DAOTest.main(DAOTest.java:263)
Caused by: java.sql.BatchUpdateException: Batch-Eintrag 0 update tbl_topo_report set fk_imported_geometries=3 where id_topo_report=329 wurde abgebrochen. Rufen Sie 'getNextException' auf, um die Ursache zu erfahren.
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2530)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2592)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
... 10 more
13:50:46,521 DEBUG ConnectionManager:476 - registering flush end
I hope you can help me and tell what I am currently doing wrong and how I can solve this problem.
Best regards,
TMK