到目前为止,我对Gson / Jackson一无所知。请多多包涵。我必须将我的对象转换为json字符串。我曾尝试过 Gson 和 Jackson 。我的对象有一个默认为Fetch的集合,它是Lazy load。当我使用session.get
获取对象并使用Gson' s gson.toJson(object);
进行转换时,它无法初始化该延迟集合。
我只是想要任何方式它应该返回null或清空任何东西,而不是搞乱延迟加载集合。因为据我所知,如果它的hibernate依赖,则无法将其从会话中取出。是否有任何解决方法(在Gson或Jackson中都有)这个问题cox我不想总是初始化集合(但有时肯定)
@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();
}
它抛出
org.hibernate.LazyInitializationException:懒得初始化角色集合:com.company.entity.Category.itemList,无法初始化代理 - 没有会话
答案 0 :(得分:1)
I will post an answer to this, because it is not a dupe of the questions cited here. There is another question targeting Jackson, but that answer covers only Jackson. Hibernate and Jackson lazy serialization
Before you persist your object with Gson
, you need to make sure, that your collections are no more filled with proxies and that the lazy collections are really null
and not a proxy that will fail if not in a session (this is the LazyInitializationException
you are receiving.
As presented in this question, you can ask hibernate to give you the implementation object instead of the proxy with this code (quoting from Converting Hibernate proxy to real object):
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;
}
In your case, I suppose you do not want the initialize()
call to happen, so I commented that line out.
Your code should now read:
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();
}
Update: As for the comment, your class is not a proxy anymore. Another suggestion is to use a custom Gson serializer.
I won't give a full example, but you can find a discussion here: https://groups.google.com/forum/?nomobile=true#!topic/google-gson/kDZjEXap_PE
Basically, you rgister a Gson type adapter for collection or list types. Then you use Hibernate.isInitialized()
on the collection object. If it is, you will serialize it, if it isn't, you return null.