Java Gson和Jackson都无法初始化惰性集合
到目前为止,我对格森/杰克逊没有深入的了解。请容忍我。我必须将我的对象转换为json字符串。我试过Gson和Jackson。我的对象有一个集合,默认情况下该集合具有Fetch,这是延迟加载。当我使用Java Gson和Jackson都无法初始化惰性集合,java,json,hibernate,jackson,gson,Java,Json,Hibernate,Jackson,Gson,到目前为止,我对格森/杰克逊没有深入的了解。请容忍我。我必须将我的对象转换为json字符串。我试过Gson和Jackson。我的对象有一个集合,默认情况下该集合具有Fetch,这是延迟加载。当我使用session.get获取对象时,使用Gson的Gson.toJson(对象)进行转换它无法初始化该惰性集合 1.我不想让你失望。 2.我也不想忽视它。 我只是希望它能够返回null或空值,而不是与延迟加载集合相混淆。因为据我所知,如果它依赖于hibernate,那么就不可能将它从会话中取出。对于这个
session.get获取对象时,使用Gson的Gson.toJson(对象)进行转换代码>它无法初始化该惰性集合
1.我不想让你失望。
2.我也不想忽视它。
我只是希望它能够返回null或空值,而不是与延迟加载集合相混淆。因为据我所知,如果它依赖于hibernate,那么就不可能将它从会话中取出。对于这个问题(在Gson或Jackson中)有什么解决办法吗?我不想总是初始化集合(但有时是肯定的)
它抛出
org.hibernate.LazyInitializationException:未能延迟初始化角色集合:com.company.entity.Category.itemList,无法初始化代理-无会话
我将发布一个答案,因为它不是这里引用的问题的副本。还有一个问题是针对杰克逊的,但答案只包括杰克逊
在使用Gson
持久化对象之前,您需要确保您的集合不再充满代理,并且惰性集合实际上是null
,并且不是一个如果不在会话中就会失败的代理(这是您收到的LazyInitializationException
)
如本问题所述,您可以要求hibernate使用以下代码为您提供实现对象,而不是代理(引用自):
更新:至于注释,您的类不再是代理。另一个建议是使用自定义Gson序列化程序
我不会给出一个完整的例子,但您可以在这里找到一个讨论:
基本上,您可以为集合或列表类型启动一个Gson类型适配器
在集合对象上。如果是,您将对其进行序列化,如果不是,您将返回null。您可以调试代码并检查,您将要序列化的对象是否真的是瞬态的,并且不再是代理吗?GSON被实现为忽略null值,因此它应该忽略null集合。但是,如果您有代理对象,集合在那里,但当您尝试在会话外部使用它时,它将异常失败。@t从hibernate会话获取对象后,如何显式地使对象成为临时对象或代理?您能解释一下吗?我正在使用@JsonInclude(Include.NON_NULL)但错误仍然存在。感谢您的回复。实际上类别本身不是代理,它只包含itemList,它是PersistentBag,我不想加载它,这意味着我不想hibernate查询数据库中的条目。它应该只返回null或空。在上面的代码中,当我将类别对象传递给此函数条件实体时HibernateProxy实例失败。
@Entity
@JsonInclude(Include.NON_NULL)
public class Category {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany
private List<Item> itemList;
//getter setter
}
Session s = sessionFactory.openSession();
Transaction t = s.getTransaction();
t.begin();
Category category = null;
try{
category = s.get(Category.class, 1);
t.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
s.close();
}
try {
Gson json = new Gson();
String categoryString = json.toJson(category);
System.out.println(categoryString);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
public static <T> T initializeAndUnproxy(T entity) {
if (entity == null) {
throw new
NullPointerException("Entity passed for initialization is null");
}
// Hibernate.initialize(entity);
if (entity instanceof HibernateProxy) {
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer()
.getImplementation();
}
return entity;
}
Session s = sessionFactory.openSession();
Transaction t = s.getTransaction();
t.begin();
Category category = null;
try {
category = s.get(Category.class, 1);
t.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
s.close();
}
try {
// No more hibernate messing with my object...
Category theRealThing = initializeAndUnproxy(category);
Gson json = new Gson();
String categoryString = json.toJson(theRealThing);
System.out.println(categoryString);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}