我有一个包含子对象列表的父对象。当我获取这些父对象的列表(以在网格中显示)时,我不想要所有子对象 - 这只是浪费时间和内存。但是,当我获取单个父级(以在不同页面上显示父级的所有详细信息)时,我确实需要其子级的列表。
class Parent {
String name;
List<Child> children;
}
class Child {
String name;
Date birthDate;
}
因此,我在 Children 上设置了延迟获取,以便默认情况下不会返回 Children(获取列表时),但我可以将 FetchMode 设置为 JOIN,以在以下情况下返回单个 Parent 的完整对象(Parent + Children):我要它。这工作得很好。
但是,对于查询这两组数据以将其“返回”到 JSP 屏幕的操作类,我使用 Gson.toJson(object) 对其进行格式化。这会引发 LazyInitializationException,因为它试图获取 Children。当我不需要这些数据时,我不希望获取子级。
因此,这提出了一些关于如何“解决”这种情况的问题:
1)我可以告诉/配置 Gson 不获取丢失的延迟获取子项吗?
2)如果没有,是否有 Gson 的替代 Json 格式化程序会尊重 hibernate 延迟获取?
3) 除了使用 json 格式之外,我的操作类是否还有另一种方法可以返回或访问从数据库获取到 JSP 的 Java bean 对象,以便数据可用于填充字段和网格?
最佳答案
我获取了 Sandhu 提供的链接,该链接导致在此处从序列化和反序列化中排除字段:
https://sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserializ
使用这个策略,我得到了这个:
class Parent {
String name;
transient List<Child> children;
}
当我从数据库中检索完整对象(带有子对象)时,我使用这个:
Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.STATIC).create();
这有点倒退,因为默认值是 TRANSIENT 和 STATIC,因此将排除设置为仅 STATIC 意味着包含 TRANSIENT。 (我认为他们需要一个 includeFieldsWithModifiers() 方法)。
总而言之,延迟获取是在hbm.xml中定义的,当我需要所有数据时,我用FetchMode.JOIN覆盖它。 Gson 默认忽略未获取的 transient 属性,当我需要所有数据“jSoned”时,我用 excludeFieldsWithModifiers 覆盖它。
我不确定我对这个设置是否 100% 满意,因为“ transient ”可能还有一些我尚未发现的其他效果。如果是这样,那么我想我可以设置一个用户定义的排除策略来阻止 jSon 触及该未获取的属性。
IMO 我认为 Gson 在“ secret ”获取我知道我没有也不想要的数据方面超出了其界限。对我来说,它应该只是将对象中的任何数据转换为字符串。我认为这是一个简单的对象字符串转换实用程序 - 我可以在一个小时内编写的东西。但如果它需要更复杂,它至少应该有一个“简单”转换选项 - tojSonSimple()。
一个后续问题 - 将属性设置为 transient 是否会产生我应该了解的任何其他不良影响?
关于java - Hibernate + 惰性获取 + gson = LazyInitializationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25341787/