如何使用 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(数据传输对象)对我来说是最持久的解决方案。
为了避免使用 .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(数据传输对象)对我来说是最持久的解决方案。