2014-05-12 162 views
2

我有一个REST项目,它使用Gson库来产生和消耗我的实体。Gson序列化抛出LazyInitializationException

但我遇到了问题。具有通过LAZY提取映射的集合的实体在由Gson序列化时生成LazyInitializationException。

我知道异常是因为在休眠会话关闭时访问了一个集合而引发的。但就像Gson的一种形式,忽略未初始化的懒惰集合,它有可能吗?

App类是受影响的,当你的appUsers属性序列,其中的一个生成错误的问题:

App.java:

AppUser.java:

@Entity 
@Table(name = "tb_app_user") 
@AssociationOverrides({ 
    @AssociationOverride(name = "id.app", 
     joinColumns = @JoinColumn(name = "id_app", nullable = false)), 
    @AssociationOverride(name = "id.user", 
     joinColumns = @JoinColumn(name = "id_user", nullable = false)) }) 
public class AppUser implements Serializable { 

    @EmbeddedId 
    private AppUserId id; 
} 

A ppUserId.java:

@Embeddable 
public class AppUserId implements Serializable { 

    @ManyToOne 
    private App app; 

    @ManyToOne 
    private User user; 
} 

已经,谢谢!

+0

您的问题是什么?什么是LazyInitializationException? –

+0

当我的Gson提供程序在App.java序列化中抛出'org.hibernate.LazyInitializationException'时,发生了我的问题。 – falvojr

+0

我没有问你的问题。你的问题是什么? –

回答

2

这意味着当您的JSON序列化发生时,您的Hibernate会话关闭。添加此到你的web.xml可以帮助(这是JPA,如果你正在使用Hibernate的纯正,有对于一个Hibernate过滤器太):

<filter> 
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> 
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> 
    <async-supported>true</async-supported> 
</filter> 



<filter-mapping> 
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

如果没有帮助,您可能需要覆盖GSON的映射占未初始化的持久化集合,这里是一些代码:

import org.hibernate.collection.internal.AbstractPersistentCollection; 

public class PersistentCollectionUtils { 
    public boolean isAbstractPersistentCollection(Object object) { 
     return object instanceof AbstractPersistentCollection; 
    } 

    public boolean wasAbstractPersistentCollectionInitialized(Object collection) { 
     return ((AbstractPersistentCollection) collection).wasInitialized(); 
    } 

    public boolean isObjectSafeToUse(Object object) { 
     return isAbstractPersistentCollection(object) ? 
       wasAbstractPersistentCollectionInitialized(object) : 
        true; 
    } 

    public boolean tryToInitializeCollection(Collection<?> collection) { 
     if(collection != null) { 
      try { 
       collection.iterator().hasNext(); 
       return true; 
      } catch (Exception t) {} 
     } 
     return false; 
    } 
} 

下面是使用示例代码(这个特殊的实现是推土机,但你可以很容易地把它翻译成GSON的映射器/适配器版) 。

public class PersistentSetMapper implements CustomFieldMapper { 

    private PersistentCollectionUtils mapperUtils = new PersistentCollectionUtils(); 

    @Override 
    public boolean mapField(Object source, Object destination, Object sourceFieldValue, ClassMap classMap, FieldMap fieldMapping) { 
     // return true => the field has been mapped, no need to map it further 
     // return false => the field was not mapped, use downstream mappers 

     // check if field is derived from Persistent Collection 
     if (!mapperUtils.isAbstractPersistentCollection(sourceFieldValue)) { 
      return false; 
     } 

     // check if field is already initialized 
     if (mapperUtils.wasAbstractPersistentCollectionInitialized(sourceFieldValue)) { 
      return false; 
     } else { 
      // if not initialized, try to initialize it 
      boolean wasInitialized = mapperUtils.tryToInitializeCollection((Collection<?>) sourceFieldValue); 
      if(wasInitialized) { 
       return false; 
      } else { 
       destination = null; 
       return true; 
      } 
     } 
    } 
}