Как правильно сохранить javax.persistence.ManyToOne - PullRequest
1 голос
/ 09 мая 2011

Сегодня действительно мой день потянет за волосы.

Я хотел бы сохранить новый объект с отношением ManyToOne, где цель может существовать или не существовать.

Мой текущий подход заключается в том, чтобы сначалаПопробуйте прочитать цель из БД, используя уникальный атрибут.

Если это не удастся, я создаю и сохраняю новую цель.Но из файлов журнала я вижу, что объект был найден, а часть create и persist не была вызвана.

Я установил целевой атрибут из исходного объекта в целевой объект.Последнее, что я пытаюсь сохранить исходную сущность.

В конце я получаю «java.lang.IllegalStateException: во время синхронизации был обнаружен новый объект через связь, которая не была помечена каскадным PERSIST»

Кажется, это полная чушь.ЭнТи был просто свежо прочитан из БД, почему каскад PERSIST.

Я могу предоставить весь источник - но все это Scala может запутать больше, чем поможет.

Определение ManyToOne

     /**
      * 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

Обратите внимание, что «Создать пользователя» не там, где видно в журналефайл - так что пользователь был найден в порядке.

Ответы [ 2 ]

1 голос
/ 10 мая 2011

Убедитесь, что вы нашли целевой объект в том же контексте постоянства (тот же EntityManager / транзакция). Также убедитесь, что его идентификатор был сопоставлен правильно. Пожалуйста, включите полную трассировку стека исключений и код, который вы используете для сохранения объекта.

1 голос
/ 09 мая 2011

Попробуйте @persistence.ManyToOne(cascade = CascadeType.PERSIST)

...