Spring Cloud Function(GCP 适配器)抛出 Hibernate 惰性无法初始化代理 - 无会话
Spring Cloud Function (GCP adapter) throws Hibernate lazy could not initialize proxy - no session
这是 Spring 中的一个常见错误,当尝试自动转换实体对象时会使用一些休眠代理,但我不知道如何加载 Jackson DataType Hibernate5 模块在 Spring 云函数 gcp 适配器.
@SpringBootApplication
@Log4j2
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
log.info("configurando cors");
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
};
}
@Bean
public Module datatypeHibernateModule() {
log.info("Cargando modulo hibernate jackson");
return new Hibernate5Module();
}
}
如果我使用与普通 Spring 引导 项目相同的代码,模块可以工作,但在这种情况下,我在日志中发现适配器未使用 Jackson 他们实现了 Gson.
at com.google.gson.Gson.toJson(Gson.java:638)
at com.google.gson.Gson.toJson(Gson.java:618)
at org.springframework.cloud.function.json.GsonMapper.toJson(GsonMapper.java:70)
我的第一个解决方法是更改 String 的 Page 对象并手动使用 jackson 映射器。
public class ObtenerEstados implements Function<Void, String> {
@Autowired
private EstadoService estadoService;
@SneakyThrows
@Override
public String apply(Void unused) {
Page<Estado> page = estadoService.buscarTodos(0, 33);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Hibernate5Module());
String objectAsString = objectMapper.writeValueAsString(page);
return objectAsString;
}
}
我在 Github 存储库上创建了两个分支
如果您已经安装了 Docker 和 Docker Compose,您可以轻松重现错误。
按照以下步骤操作:
git clone https://github.com/ripper2hl/sepomex.git
cd sepomex
git checkout -b dev origin/functions
docker-compose pull db
docker-compose up -d db
export spring_profiles_active=local
mvn -Pgcp function:run
并使用 curl 或任何 REST 客户端执行
curl http://localhost:8080/
我知道使用 DTO 对象的替代方法,但我不想使用此选项
因此,只要 Gson 在类路径上,它就会被赋予优先级,当然 Google 也是如此。请设置spring.http.converters.preferred-json-mapper=jackson
属性强制Jackson
最后我用这段代码修复了
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public JsonMessageConverter jsonMessageConverter() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Hibernate5Module());
JacksonMapper jacksonMapper = new JacksonMapper(objectMapper);
return new JsonMessageConverter(jacksonMapper);
}
}
文档解释 Gson 是默认的 MessageConverter 但不清楚如何将 gson 更改(更简单)为 jackson。
这是 Spring 中的一个常见错误,当尝试自动转换实体对象时会使用一些休眠代理,但我不知道如何加载 Jackson DataType Hibernate5 模块在 Spring 云函数 gcp 适配器.
@SpringBootApplication
@Log4j2
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
log.info("configurando cors");
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
};
}
@Bean
public Module datatypeHibernateModule() {
log.info("Cargando modulo hibernate jackson");
return new Hibernate5Module();
}
}
如果我使用与普通 Spring 引导 项目相同的代码,模块可以工作,但在这种情况下,我在日志中发现适配器未使用 Jackson 他们实现了 Gson.
at com.google.gson.Gson.toJson(Gson.java:638)
at com.google.gson.Gson.toJson(Gson.java:618)
at org.springframework.cloud.function.json.GsonMapper.toJson(GsonMapper.java:70)
我的第一个解决方法是更改 String 的 Page 对象并手动使用 jackson 映射器。
public class ObtenerEstados implements Function<Void, String> {
@Autowired
private EstadoService estadoService;
@SneakyThrows
@Override
public String apply(Void unused) {
Page<Estado> page = estadoService.buscarTodos(0, 33);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Hibernate5Module());
String objectAsString = objectMapper.writeValueAsString(page);
return objectAsString;
}
}
我在 Github 存储库上创建了两个分支
如果您已经安装了 Docker 和 Docker Compose,您可以轻松重现错误。
按照以下步骤操作:
git clone https://github.com/ripper2hl/sepomex.git
cd sepomex
git checkout -b dev origin/functions
docker-compose pull db
docker-compose up -d db
export spring_profiles_active=local
mvn -Pgcp function:run
并使用 curl 或任何 REST 客户端执行
curl http://localhost:8080/
我知道使用 DTO 对象的替代方法,但我不想使用此选项
因此,只要 Gson 在类路径上,它就会被赋予优先级,当然 Google 也是如此。请设置spring.http.converters.preferred-json-mapper=jackson
属性强制Jackson
最后我用这段代码修复了
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public JsonMessageConverter jsonMessageConverter() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Hibernate5Module());
JacksonMapper jacksonMapper = new JacksonMapper(objectMapper);
return new JsonMessageConverter(jacksonMapper);
}
}
文档解释 Gson 是默认的 MessageConverter 但不清楚如何将 gson 更改(更简单)为 jackson。