2013-10-07 18 views
2

插入many2one的兩個對象我使用postgreql(如事項)和我有兩個班,這個映射時產生錯誤現在,這段代碼運行時:Hibernate的同時

Session session = getSession(); 
Transaction transaction = session.getTransaction(); 
transaction.begin(); 

TokenizedForm form = new TokenizedForm("my fm", "body of it here"); 
session.save(form); 

FormTokens ft0 = new FormTokens("my token 1", "[[]]"); 
ft0.setForm(form); 

FormTokens ft1 = new FormTokens("my t1", "<<>>"); 
ft1.setForm(form); 

session.save(ft0); 
session.save(ft1); 

transaction.commit(); 

我得到如下:

Hello World! 
log4j:WARN No appenders could be found for logger (org.jboss.logging). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: select max(ID) from TOKENIZEDFORM 
Hibernate: select max(ID) from FORMTOKENS 
Hibernate: insert into TOKENIZEDFORM (NAME, BODY, ID) values (?, ?, ?) 
Hibernate: insert into FORMTOKENS (TEXT, DELIMITER, FORM, ID) values (?, ?, ?, ?) 
Hibernate: insert into FORMTOKENS (TEXT, DELIMITER, FORM, ID) values (?, ?, ?, ?) 
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:125) 
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110) 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136) 
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:58) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3067) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3509) 
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88) 
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:369) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:286) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:339) 
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) 
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234) 
    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.mydomain.App.d(App.java:55) 
    at com.mydomain.App.main(App.java:22) 
Caused by: org.postgresql.util.PSQLException: ERROR: insert or update on table "formtokens" violates foreign key constraint "fk_37kmr0diunms0vx0boagmc43f" 
    Detail: Key (id)=(3) is not present in table "tokenizedform". 
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102) 
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835) 
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257) 
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500) 
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388) 
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334) 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133) 
    ... 15 more 

其中3是FormToken的ID。不是數據庫中的TokenizedForm。 (tf0和tf1的id是2和3,因爲我已經將1行插入數據庫)。
如果我嘗試只添加一個FormToken 它在每次運行中都有效!此問題發生在一次運行中添加的兩個或更多FormTokens實例。我可以通過在每次運行期間只添加一個FormTokens實例來添加億萬FormTokens。
我試圖從TokenizedForm刪除FormToken的任何痕跡,但(從映射中刪除設置和...),但沒有任何區別,我甚至嘗試提交併在一個FormToken插入後開始新的事務。我試圖關閉並開啓新的會議!但同樣的事情一遍又一遍地發生。
我在做什麼錯?

+0

您是否也嘗試過form.getTokens()。add(ft0)和 form.getTokens()。add(ft1)and session.saveOrUpdate(form) – Zeus

+0

另外,您能否提供FK和PK細節的表結構 – Zeus

回答

1

有關如何映射雙向one-to-meny關聯的信息,請參見the documentation。您的映射是錯誤的,因爲它告訴,在

<set lazy="true" name="tokens" sort="unsorted" table="FORMTOKENS"> 
    <key> 
    <column name="ID" sql-type="INTEGER"/> 
    </key> 
    <one-to-many class="com.mydomain.models.FormTokens"/> 
</set> 

在formtokens ID列是用來指tokenizedforms表的主鍵。它應該是

<set lazy="true" name="tokens" sort="unsorted" table="FORMTOKENS"> 
    <key> 
    <column name="FORM" sql-type="INTEGER"/> 
    </key> 
    <one-to-many class="com.mydomain.models.FormTokens"/> 
</set> 

改爲。當然,請確保從頭開始重新生成數據庫模式,讓Hibernate爲您生成數據庫模式,因爲它可能會生成一個FK約束,當您試圖完全刪除該集合時,該約束不會被刪除。