Search code examples
spring-boothibernatejacksongsonspring-cloud-function

Spring Cloud Function (GCP adapter) throws Hibernate lazy could not initialize proxy - no session


This is a common error in Spring when tries to transform automatically an entity object whit some hibernate proxys but i dont't know how to load Jackson DataType Hibernate5 module in Spring cloud functions gcp adapter.

@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();
    }
}

If i use the same code whit normal Spring boot project the module works but in this case i found on the log the adapter don't used Jackson and they implements 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

My first workaround is change the Page object for String and use manually jackson mapper.

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

I created two branches on the Github repository

If you haved already installed Docker and Docker Compose you can reproduce the bug easy.

Follow the next steps:

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

And execute with a curl or any REST client

curl http://localhost:8080/

I know the alternative for use a DTO object but i prefer not use this option


Solution

  • So whenever Gson is on the classpath it is given priority and of course with Google that is the case. Please set spring.http.converters.preferred-json-mapper=jackson property to force Jackson.