java - Criteria.list() 期间出现 org.hibernate.TransientObjectException

标签 java hibernate

我在 Internet 上看到了很多关于如何在保存/更新/删除期间修复 TransientObjectExceptions 的帖子,但是我在根据我的条件调用列表时遇到了这个问题。

我有两个对象 A 和 B。A 有一个名为 b 的字段,它属于 B 类型。在我的映射中,b 被映射为多对一。这一切都在一个更大的持久性框架中运行(该框架有点像 Core Data),因此我不在我的 hibernate 映射中使用任何级联,因为级联是在更高级别处理的。

这是围绕我的标准的有趣代码:

A a = new A();
B b = new B();
a.setB(b);

session.save("B", b); // Actually handled by the higher level
session.save("A", a); // framework, this is just for clarity

// transaction committed and session closed
...
// new session opened

Criteria criteria = session.createCriteria(A.class);
criteria.add(Restrictions.eq("b", b));
List<?> objects = criteria.list();

基本上我正在寻找 A.b 等于 b 的特定实例的所有类型的对象(我实际上尝试重组查询以便我传递 b 的 id 只是为了确保 b 不会导致我问题)。

这是我调用 criteria.list() 时发生的堆栈跟踪:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: B
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:244)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:449)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:141)
at org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1769)
at org.hibernate.loader.Loader.bindParameterValues(Loader.java:1740)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1612)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
at org.hibernate.loader.Loader.doList(Loader.java:2294)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2172)
at org.hibernate.loader.Loader.list(Loader.java:2167)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1706)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)

这是我的映射:

<class entity-name="A" lazy="false">
<tuplizer entity-mode="dynamic-map" class="MyTuplizer" />
<id type="long" column="id">
<generator class="native" />
</id>
<many-to-one name="b" entity-name="B" column="b_id" lazy="false" />
</class>

<class entity-name="B" lazy="false">
<tuplizer entity-mode="dynamic-map" class="MyTuplizer" />
<id type="long" column="id">
<generator class="native" />
</id>
</class>

谁能帮我弄清楚为什么在获取过程中会出现 TransientObjectException?最好我想找到一个不依赖级联的解决方案,因为它们往往会掩盖更高级别框架中发生的问题。

最佳答案

问题是 b 在另一个 session 中持久存在,该 session 已关闭并在新 session 中创建查询。当 session 关闭时,其持久性上下文中的所有对象都将分离。如果您想稍后在另一个 session 中重用它们,您需要先将它们重新附加到该 session :

session.update(b);

引自 Hibernate 书:

The update() operation on the Session reattaches the detached object to the persistence context and schedules an SQL UDPATE. Hibernate must assume that the client modified the object while it was detached. (Otherwise, if you’re certain that it hasn’t been modified, a lock() would be sufficient.) The persistence context is flushed automatically when the second transaction in the conversation commits, and any modifications to the once detached and now persistent object are synchronized with the database.

The saveOrUpdate() method is in practice more useful than update(), save(), or lock(): In complex conversations, you don’t know if the item is in detached state or if it’s new and transient and must be saved. The automatic state-detection provided by saveOrUpdate() becomes even more useful when you not only work with single instances, but also want to reattach or persist a network of connected objects and apply cascading options.

请注意,还有一个 merge() 方法,用于在可以重新附加旧的分离实例之前将同一实体加载到新的持久化上下文中的情况。在这种情况下,您有两个物理上不同的实例代表同一个实体,因此应该合并它们以避免 NonUniqueObjectException

关于java - Criteria.list() 期间出现 org.hibernate.TransientObjectException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2603323/

相关文章:

java - 使用java计算两个csv GPS点之间的距离

带有数组中对象的 Java NullPointerException

java - 如何在文本/纯 servlet 响应中换行

java - 如何编写 Hibernate HQL 查询来删除所有 "grand children"元素?

Hibernate saveorUpdate方法问题

java - Hibernate + Jasypt : Unable to resolve name . ..作为策略

java - Java Hibernate 中的日期转换

java - Eclipse - Android 应用程序崩溃

java - Java 中的 map 大小不正确。如果我将 Key 和 Value 包装在 WeakReference 中,然后添加到 HashMap 中,打印的大小与预期不同

java - Hibernate 示例未找到任何实例