session.buildLockRequest上的HibernateException,其中byte []为主键

时间:2012-03-15 15:01:31

标签: hibernate bytearray hibernateexception

我有一个用户和credit_card实体,用户有一个credit_card集合。我所拥有的这两个实体的主键是byte []。

第一次会议:   - 我开了一个新的会议。   - 对users表进行条件查询,实际上是访问DB并获取user + credit_cards,最后我有一个用户对象说userObj。   - 关闭会话。

第二次会议:   - 我开了另一场会议。   - 尝试调用session.buildLockRequest(LockOptions.NONE).lock(userObj);

现在hibernate将尝试重新附加分离的对象,但是我得到以下错误:

org.hibernate.HibernateException: reassociated object has dirty collection reference
at org.hibernate.event.def.OnLockVisitor.processCollection(OnLockVisitor.java:71)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:122)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:83)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:77)
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:144)
at org.hibernate.event.def.AbstractReassociateEventListener.reassociate(AbstractReassociateEve    ntListener.java:101)
at   org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:82)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:774)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:766)
at org.hibernate.impl.SessionImpl.access$600(SessionImpl.java:156)

我尝试在hibernate代码中调试它,并发现,hibernate试图检查传递的对象的集合(credit_cards)是否实际上由用户拥有(即user1)。

所以在hibernate代码的深处,看起来它正在检查传递对象(即user1)的主键的 equals方法与另一个对象是什么相等。调用快照对象。 由于byte []本质上是一个数组,并且在等于检查时失败并抛出上述错误。 我知道我可以在一次会议中完成上述工作,但这仅仅是一个场景。

我尝试使用Long / Integer作为主键,它工作得很好,因为它通过了相等性检查。

Hibernate版本:3.6.9.Final(我试着看一下4.1.1.Final版本,但抛出此错误的文件/代码不会改变) DB:SQL服务器

这是休眠问题还是我做错了什么?

2 个答案:

答案 0 :(得分:1)

使用String而不是byte []作为主键。它可以携带相同的值并通过等于方法

String myId = new String(bytes);

myId.getBytes();

这不是一个休眠问题。

答案 1 :(得分:1)

这不是Hibernate的问题。 ID的类必须实现hashCode并且正确等于。 byte[]没有,因此它不是有效的ID类。使用byte []作为ID是IMO,这是一个非常糟糕的主意。 A Long是一个非常好的主意。如果你真的想保留你的字节数组,那么将它包装成自定义类型,或使用Base64或Hex编码将其转换为String。