1

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

第一次会议: - 我开了一个新会议。- 对用户表进行条件查询,该表实际上进入数据库并获取用户 + 信用卡,最后我有一个用户对象说 userObj。- 关闭会话。

第二个会话: - 我打开了另一个会话。- 试图调用 session.buildLockRequest(LockOptions.NONE).lock(userObj);

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

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)

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

因此,在休眠代码的深处,它似乎正在检查传递对象(即 user1)和另一个对象的主键的equals 方法是否相等,它正在调用快照对象。由于 byte[] 本质上是一个数组,并且在等于检查时失败并抛出上述错误。我知道我可以在一个会话中完成上述工作,但这只是一个场景。

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

休眠版本:3.6.9.Final(我也尝试查看 4.1.1.Final 版本,但引发此错误的文件/代码未更改) DB:SQL 服务器

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

4

2 回答 2

1

这在 Hibernate 中不是问题。ID 的类必须正确实现 hashCode 和 equals。byte[]没有,所以它不是一个有效的 ID 类。在 IMO 中,使用 byte[] 作为 ID 是一个非常糟糕的主意。Long 是一个更好的主意。如果您真的想保留字节数组,请将其包装成自定义类型,或使用 Base64 或十六进制编码将其转换为字符串。

于 2012-03-15T15:13:59.093 回答
1

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

String myId = new String(bytes);

myId.getBytes();

这不是休眠问题。

于 2012-03-15T15:08:50.417 回答