java - Gson序列化抛出LazyInitializationException

标签 java json hibernate rest gson

我有一个 REST 项目,它使用 Gson 库来生成和使用我的实体。

但我对此有疑问。通过 LAZY fetch 映射集合的实体在由 Gson 序列化时会生成 LazyInitializationException。

我知道引发异常是因为在 hibernate session 关闭时访问了集合。但是就像 Gson 的一种形式忽略未初始化的惰性集合一样,这可能吗?

App 类是受影响的类之一,当您的 appUsers 属性被序列化时,会生成相关错误:

App.java:

@Entity
@Table(name = "tb_app")
public class App implements Serializable {

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "id.app", cascade = CascadeType.ALL)
    private Set<AppUser> appUsers;
}

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;
}

AppUserId.java:

@Embeddable
public class AppUserId implements Serializable {

    @ManyToOne
    private App app;

    @ManyToOne
    private User user;
}

已经,谢谢!

最佳答案

这意味着当您的 JSON 序列化发生时,您的 Hibernate session 将关闭。将其添加到您的 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;
    }
}

下面是使用的示例代码(这个特定的实现是针对 Dozer 的,但您可以轻松地将其转换为 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;
            }
        }
    }
}

关于java - Gson序列化抛出LazyInitializationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23620716/

相关文章:

javascript - 使用 AngularJS 中的数据更新 JSON 文件

java - hibernate - 内存不足插入大 Blob

Java 异常和 throw 子句

onCreate 的 java.lang.NoSuchMethodException

python - 使用 json 和 python 序列化/反序列化对象列表

c# - 如何禁用 Newtonsoft JSON 序列化程序中的对象引用创建?

java - 使用 JPA 的 UUID 映射类型

java - 在@Entity中使用@Cache会出现错误

java - 我们如何使用 java 将复杂的 NativeQuery 结果映射到 DTO 对象

java - JUnit + Apache Camel