如何使用 Hibernate4Module

How to use Hibernate4Module

为了避免使用 .size 手动加载字段,我想实现 Hibernate4Module。不幸的是,在所有配置方面都是新手,我似乎无法让它发挥作用。我一直从 java 得到的是:Could not write content: could not initialize proxy - no Session.

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"servlet.controller"})
public class ServletConfig extends WebMvcConfigurerAdapter {
    ...
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        ObjectMapper mapper = null;
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                mapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();

            }
        }
        if (mapper == null) {
            MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
            converter.setObjectMapper(mapper = new ObjectMapper());
            converters.add(converter);
        }
        Hibernate4Module hbm = new Hibernate4Module();
        hbm.enable(Feature.FORCE_LAZY_LOADING);
        mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
               .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.registerModule(hbm);
    }
    ...
}

有人能看出我做错了什么吗?

注意

我已经 运行 研究了一些效率缺陷,我正在研究在 DTO 之外减轻它们的可行性。我对DTO方法非常熟悉,我目前正在开发的软件包含60个名为"Ext*.java"的文件(包含使用Gson的DTO)。其中每一个的长度都在 100 到 1000 行之间,并且大大增加了控制器方法的长度。此外,我们将尝试添加更多单元测试。因此,我迫切希望找到一种尽可能多地消除 DTO 代码的方法。也就是说,我一点也不反对在需要时使用 DTO,事实上我刚刚完成了我的第一个 StdSerializer

整个美国大陆有大约 20 人在做一个项目,我只是希望能够对混乱施加一些秩序。

您遇到异常是正常的 Hibernate4Module 不会保持会话打开,它不是为此目的。如果你想保持 EntityManager/Session 在请求范围内打开,你可以使用 OpenEntityManagerInViewInterceptor.

要在 Java 配置中注册,您必须在 WebMvcConfigurerAdapter class 中添加:

    @Autowired
    private EntityManagerFactory emf;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        OpenEntityManagerInViewInterceptor interceptor = new OpenEntityManagerInViewInterceptor();
        interceptor.setEntityManagerFactory(emf);
        registry.addWebRequestInterceptor(interceptor);
    }

但出于多种原因,我不建议将它与 Jackson 一起使用。

首先,它被称为 Anti-pattern,您应该在实施它之前真正考虑所有的影响(后面的连接保持更长的时间,中断关注的分离...)。此外,您还要承担根据 JPA 模型加载所有数据库的风险,并且您将不得不处理 Jackson 的无限递归问题。

手动触发延迟加载乍一看可能很痛苦,但这加上使用 DTO(数据传输对象)对我来说是最持久的解决方案。