2011-05-09 114 views
1

今天真的是我的頭髮拉一天。如何正確保存javax.persistence.ManyToOne

我想堅持一個新的對象與ManyToOne關係的目標可能存在或不存在。

我目前的做法是先嚐試使用獨特的屬性從數據庫中讀取目標。

如果這樣做失敗了,我會創建並堅持一個新的目標。但是從日誌文件中,我可以看到該對象已找到,並且創建和保留部分未被調用。

我將源實體的目標屬性設置爲目標實體。最後,我嘗試堅持源實體。

最後我得到«java.lang.IllegalStateException:在同步的新對象是通過沒有標記級聯關係發現PERSIST»

這似乎是完全胡說八道。該實體只是從數據庫中仔細閱讀,爲什麼級聯PERSIST是。

我可以提供整個源代碼 - 但它是所有Scala,可能會混淆更多,然後它可以幫助。

多對一定義

 /** 
     * User who's time is recorded. 
     */ 
    @persistence.JoinColumn (nullable = false) 
    @persistence.ManyToOne 
    private [this] var Benutzer: Benutzer = _ 

    /** 
     * User who's time is recorded. 
     * 
     * @return a copy of the Benutzer 
     */ 
    def getBenutzer = this.Benutzer 

    /** 
     * Project short name (i.E. "a20999002006") 
     * 
     * @param a new Benutzer 
     */ 
    def setBenutzer (Benutzer: Benutzer) = 
    { 
     if (Benutzer == null) 
     { 
      val Exception = new IllegalArgumentException ("Benutzer must be set.") 
      Zeitstempel.logger.log (logging.Level.FINE, "Throw:", Exception) 
      throw Exception 
     } 
     else 
     { 
      this.Benutzer = Benutzer 
     } // if 
    } // setBenutzer 

我已嘗試添加級聯堅持標註爲好。但是這並沒有幫助,因爲我得到了一個唯一的約束例外。

堅持日常

 /** 
     * Add a 「Kommen」 time to the database. 
     * 
     * @param uhrzeit Time to record 
     */ 
    @javax.annotation.security.RolesAllowed (Array ("employee", "manager")) 
    override def Add (entry: Zeitstempel) = 
    { 
     val Search_Benutzer = entry getBenutzer 
     val Query_Benutzer = entityManager createNamedQuery "Find_Benutzer_By_User_ID" 

     Query_Benutzer.setParameter ("ID", Search_Benutzer getUser_ID) 

     ZeitstempelModel.logger.log (
      logging.Level.INFO, 
      "Search user : {0}", 
      Search_Benutzer) 

     val Found_User = try 
     { 
      Query_Benutzer.getSingleResult.asInstanceOf[Benutzer] 
     } 
     catch 
     { 
      case exception: javax.persistence.NoResultException => 
       ZeitstempelModel.logger.log (
       logging.Level.INFO, 
       "Create user : {0}", 
       Query_Benutzer) 
       entityManager persist Search_Benutzer 
       Search_Benutzer 
     } // try 

     ZeitstempelModel.logger.log (
      logging.Level.INFO, 
      "Found user : {0}", 
      Found_User) 

     entry setBenutzer Found_User 
     entityManager persist entry 
    } // Add 

請注意,「創建用戶」是任何地方在日誌文件中看到 - 所以用戶發現確定。

+0

顯示'ManyToOne'定義(如果是scala,則無關緊要) – Bozho 2011-05-09 14:31:12

回答

1

嘗試@persistence.ManyToOne(cascade = CascadeType.PERSIST)

+0

這會給出重複的鍵例外:-(。 – Martin 2011-05-11 18:06:05

+0

好吧,您必須確保集合中的元素沒有已經在數據庫,或者使用CascadeType.ALL來處理合並和更新 – Bozho 2011-05-11 18:54:42

+0

'CascadeType.ALL'不會嘗試刪除Benutzer嗎?但是由於代碼中沒有刪除,所以在嘗試時沒有任何傷害; )。 – Martin 2011-05-12 07:43:30

1

確保你找到在同一個持久化上下文(相同的EntityManager /交易)的目標對象。 還要確保其Id已正確映射。 請包含完整的異常堆棧跟蹤以及用於保留該對象的代碼。

+0

我添加了代碼。明天獲取堆棧跟蹤。 – Martin 2011-05-11 18:34:15