Использование столбца @Version не допускает использование свойства отношения @ManyToOne в качестве ссылки. - PullRequest
0 голосов
/ 21 мая 2011

Я использую спящий режим 3.6.3.Final.У меня есть две реляционные сущности A & B с однонаправленным ManyToOne, определенным как:


@Entity public class A {
...
@Version @Column ( name = "ChangeNumber" )
public Long getVersion() { return version; }
@ManyToOne @JoinColumn( name = "B_ID" )
public B getRelationalB() { return relationalB; }
...
}

@Entity public class B {
@Version @Column ( name = "ChangeNumber" )
public Long getVersion() { return version; }
....
}

Теперь предположим, что у меня есть экземпляр B, сохраняемый в БД уже с pk id = 1, затем выполняю следующую операцию:

<code>
A a = new A();
a.setRelationalB( new B( 1 ) );
session.saveOrUpdate( a ) ;
выдает известное исключение «TransientObjectException: объект ссылается на несохраненный переходный процесс ...».Удивительно, но если @Version @Column удалить или сделать @Transient, приведенный выше код будет работать отлично.Есть идеи, почему я наблюдаю это поведение?

Ответы [ 2 ]

0 голосов
/ 31 мая 2013

У меня часто возникало исключение "объект ссылается на несохраненный переходный процесс ..." после добавления столбца @Version. Вот как я решил это в моем случае:

В моем сценарии проблема заключалась в внешних ключах.Код был написан так, что вместо загрузки упомянутого объекта создавал новый экземпляр и устанавливал первичный ключ , надеясь, что Hibernate сможет найти реальный.Я повторяю: до @Version все работало нормально.

Иллюстрирование:

Рассмотрим объект класса B с идентификатором 1, который существует в базе данных, и теперь мы сохраняемновый экземпляр A.

  • ранее (безрезультатно) (выдавал исключение после добавления @Version):

    a.setB (новый B (1));

    sf.getCurrentSession (). save (a);

  • исправлено (работает хорошо) - использование @Версия без проблем:

    a.setB ((B) sf.getCurrentSession (). Get (B.class, 1));

    sf.getCurrentSession (). Save (a);

При отладке Hibernate я обнаружил, что он выполняет дополнительную проверку при наличии столбца @Version.

Итак, я считаю, что люди, имеющие эту ошибку, тоже не являютсязагружая объекты, на которые они пытаются сослаться (что в любом случае лучше) или они действительно пытаются сохранить новый экземпляр B (например), но не настроили каскадное сохранениеза это.

0 голосов
/ 29 мая 2011

Проблема в том, что вы не используете объект B, который находится в базе данных

A a = new A();
// you're instantiating a "new" B with id 1, this is not the same 
// as the "object" you have in the database.
a.setRelationalB( new B( 1 ) );   
session.saveOrUpdate( a ) ;

Проблема в том, что hibernate не может распознать, что новый B, который вы создали, такой же, как тот, который хранится в БД. Если вы хотите узнать причину этого, прочитайте о шаблоне Единица работы .

попробуйте сделать что-то вроде

B b = sessions.get(B.class, 1)
A a = new A();
a.setRelationalB( b );
session.saveOrUpdate( a ) ;

С другой стороны: если вы хотите сохранить новые экземпляры обоих объектов за один раз, вам потребуется выполнить каскад .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...