2016-08-12 40 views
1

我已經越來越這惱人的異常試圖創建與我的實體管理器本機查詢創建NativeQuery。完整的錯誤信息是:IllegalStateException異常嘗試與EntityManager的

java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: [email protected] 
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects(RepeatableWriteUnitOfWork.java:313) 
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:723) 
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:441) 
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:874) 
at org.eclipse.persistence.internal.jpa.QueryImpl.performPreQueryFlush(QueryImpl.java:967) 
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:207) 
at org.eclipse.persistence.internal.jpa.QueryImpl.getSingleResult(QueryImpl.java:521) 
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getSingleResult(EJBQueryImpl.java:400) 

觸發錯誤的實際代碼是:

Query query; 
    query = entityManager.createNativeQuery(
      "SELECT MAX(CAST(SUBSTRING_INDEX(RecordID,'-',-1) as Decimal)) FROM `QueriedEntityTable`"); 
    String recordID = (query.getSingleResult() == null ? 
      null : 
      query.getSingleResult() 
       .toString()); 

這正與在doTransaction一部分的EntityTransaction執行。那就是讓我這個雖然部分是,這是第一個代碼到doTransaction方法內執行,簡化以下:

updateOneToManyEntity1(); 
updateOneToManyEntity2(); 
entityManager.merge(parentEntity); 

實體它與「OneToManyEntity1」問題不連表我試圖創建查詢。我沒有做任何堅持或合併,直到這一點,所以我也不知道是什麼原因導致它不同步。直到代碼執行完成的唯一數據庫工作只是提取數據,不會改變任何內容。外鍵在數據庫中正確設置。

我可以通過這樣做來消除這個錯誤,並將這些關係標記爲Cascade.PERSIST,但是我在query.getSingleResult()行上得到了一個MySQLContrainstraViolationException。我的日誌顯示它在此之前執行了一些INSERT查詢,所以它看起來像到達了我的doTransaction方法的EntityManager.merge部分,但是錯誤和調用堆棧指向了完全不同的代碼部分。

使用EclipseLink(2.6.1),Glassfish 4和MySQL。 entitymanager正在使用RESOURCE_LOCAL,並在持久性單元標籤下列出所有必需的類,並且exclude-unlisted-classes設置爲false。

編輯:所以有的我想通過這次合作的詳細信息。如果我在事務開始時放置一個斷點,然後通過IntelliJ的「Evaluate Expression」工具執行entityManager.clear(),至少在第一次通過時,一切正常。沒有它,我會遇到一個錯誤,因爲它試圖將空對象插入到表中。

編輯#2:我將nativeQuery部分轉換爲使用Criteria API,這讓我通過我的代碼實際完成它,以便我可以找到無意中將空對象添加到實體列表中的位置。對於爲什麼實體管理器正在緩存這些錯誤或者某些問題,我仍然感到困惑,因爲創建本機查詢的過程中斷了,因爲它仍然嘗試插入錯誤的數據。這是我在做每次之前需要調用EntityManager.clear()的東西嗎?或者我應該在doTransaction方法出現錯誤時調用它?

+0

你在哪裏放置交易邊界? –

+0

我現在想讀一讀這篇文章。不知道我是否設置了它我想或者我誤解了這個概念。我使用EntityManager.getTransaction()從實體管理器獲取事務,然後調用.begin(),.doTransaction(),然後在成功時調用.committ()或在失敗時調用.rollback()。由於其Resource_Local持久性上下文,我不認爲我需要它? – gdawgrancid

回答

0

所以返工的代碼,並預留設置此之後,我偶然在回答我的問題的至少一部分。我的問題是由事務開始之前持續存在的對象引起的。所以當我進入我的事務時,它首先嚐試從我的實體對象插入/更新數據,並拋出錯誤,因爲我沒有設置大多數非空列的值。我相信這就是我得到級聯錯誤的原因,而且我很積極,這是我在交易開始時發現的隨機插入查詢的來源。希望這可以幫助別人避免很多麻煩。

相關問題