【问题标题】:Spring Cloud Function (GCP adapter) throws Hibernate lazy could not initialize proxy - no sessionSpring Cloud Function(GCP 适配器)抛出 Hibernate lazy 无法初始化代理 - 没有会话
【发布时间】:2021-06-29 21:04:00
【问题描述】:

这是 Spring 中的常见错误,当尝试使用一些休眠代理自动转换实体对象时,但我不知道如何加载 Jackson DataType Hibernate5 模块Spring Cloud 函数 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 boot 项目相同的代码,则模块可以工作,但在这种情况下,我在日志中发现适配器没有使用 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)

This is the entire log file

我的第一个解决方法是更改​​ 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 对象的替代方法,但我不想使用此选项

【问题讨论】:

    标签: spring-boot hibernate jackson gson spring-cloud-function


    【解决方案1】:

    因此,只要 Gson 在类路径上,它就会被优先考虑,当然 Google 也是如此。请设置spring.http.converters.preferred-json-mapper=jackson属性强制杰克逊。

    【讨论】:

    【解决方案2】:

    最后我修复了这段代码

    @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。

    https://docs.spring.io/spring-cloud-function/docs/current/reference/html/spring-cloud-function.html#_provided_messageconverters

    【讨论】:

    • 以上是一个很好的解决方法,但无论如何,the issue 已修复并向后移植,并将在下一个版本中提供。
    猜你喜欢
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 2012-11-09
    • 2015-10-09
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多