Hibernate 使用@Version列不允许@ManyToOne关系属性作为引用

Hibernate 使用@Version列不允许@ManyToOne关系属性作为引用,hibernate,jpa-2.0,optimistic-locking,relational-model,Hibernate,Jpa 2.0,Optimistic Locking,Relational Model,我正在使用hibernate 3.6.3.Final。我有两个关系实体A和B,其单向多工单定义为: @Entity public class A { ... @Version @Column ( name = "ChangeNumber" ) public Long getVersion() { return version; } @ManyToOne @JoinColumn( name = "B_ID" ) public B getRelationalB() { return relatio

我正在使用hibernate 3.6.3.Final。我有两个关系实体A和B,其单向多工单定义为:


@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; }
....
}
现在假设我在db中已经有一个pk id=1的持久化B实例,然后执行以下操作:

A a = new A();
a.setRelationalB( new B( 1 ) );
session.saveOrUpdate( a ) ;

A=新的A();
a、 setRelationalB(新的B(1));
会议.保存或更新(a);
引发著名的“TransientObject异常:对象引用未保存的瞬态…”异常。 令人惊讶的是,如果删除@Version@Column或使其成为@Transient,上述代码就可以很好地工作。
知道我为什么要观察这种行为吗?

问题是您没有使用数据库中的实体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与存储在db上的B是同一个。如果您想知道这背后的原因,请阅读有关模式的内容

试着做类似的事情

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

还有一点:如果要一次性保存这两个对象的新实例,则需要执行一个操作。

问题是您没有使用数据库中的实体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与存储在db上的B是同一个。如果您想知道这背后的原因,请阅读有关模式的内容

试着做类似的事情

B b = sessions.get(B.class, 1)
A a = new A();
a.setRelationalB( b );
session.saveOrUpdate( a ) ;
还有一点:如果您想一次性保存两个对象的新实例,那么您需要执行一个操作。

在添加@Version列后,我也遇到了“对象引用未保存的瞬态…”异常以下是我在我的案例中如何解决的:

在我的场景中,问题出在外键上。编写代码是为了而不是加载引用的对象,而是创建一个新实例并设置主键,希望Hibernate能够找到真正的实例。我重复一遍:在@Version事件之前,它工作得很好

说明:

假设数据库中存在一个id为
1
的类
B
的对象,现在我们正在保存
a
的一个新实例

  • 以前(不好)(在添加@Version后出现异常):

    a、 立管局(新B(1));

    sf.getCurrentSession().save(a)

  • 修复(工作正常)-使用@Version没有问题:

    a、 setB((B)sf.getCurrentSession().get(B.class,1))

    sf.getCurrentSession().save(a)

调试Hibernate时,我发现当@Version列出现时,它会进行一些额外的检查

因此,我认为出现此错误的人要么没有加载他们试图引用的对象(无论如何这是一种更好的做法),要么他们真的试图保存
B
的新实例(例如),但没有为此配置级联保存。

我有“对象引用未保存的瞬态…”添加@Version列后也会出现很多异常以下是我在我的案例中如何解决的:

在我的场景中,问题出在外键上。编写代码是为了而不是加载引用的对象,而是创建一个新实例并设置主键,希望Hibernate能够找到真正的实例。我重复一遍:在@Version事件之前,它工作得很好

说明:

假设数据库中存在一个id为
1
的类
B
的对象,现在我们正在保存
a
的一个新实例

  • 以前(不好)(在添加@Version后出现异常):

    a、 立管局(新B(1));

    sf.getCurrentSession().save(a)

  • 修复(工作正常)-使用@Version没有问题:

    a、 setB((B)sf.getCurrentSession().get(B.class,1))

    sf.getCurrentSession().save(a)

调试Hibernate时,我发现当@Version列出现时,它会进行一些额外的检查


因此,我认为出现此错误的人要么没有加载他们试图引用的对象(无论如何这是一种更好的做法)要么他们确实试图保存
B
的一个新实例(例如),但没有为其配置级联保存。

但是第一个代码块可以工作(使用关系B持久化a)如果我不使用@Version列。这是偶然/巧合吗?但是如果我不使用@Version column,第一个代码块将起作用(用关系B持久化A)。这是偶然/巧合吗?