Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring jdbcSession : Not able to serialize JsonNode

I am trying to store a JsonNode to my spring jdbc session,
while when the data is set and ready to insert to database by spring, ConversionFailedException was throw.
I tried the same as mentioned in below, but is not working though.

No converter found capable of converting from type java.lang.Object to type byte[] in JdbcOperationsSessionRepository .

I also look into the JdbcHttpSessionConfiguration , and seem the same code is already there.

@EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 1800)
public class MyConfiguration extends WebMvcConfigurerAdapter {
}

// session class
@Component
@Scope(value = SCOPE_SESSION, proxyMode = TARGET_CLASS)
public class SessionForm implements Serializable {
    private String someOtherFeild;
    private JsonNode custom;
    ....
}

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object] to type [byte[]] for value 'com.rakuten.payment.step.app.step.model.session.SessionForm@e943f2d'; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.fasterxml.jackson.databind.node.ObjectNode
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:43)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:203)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository.serialize(JdbcOperationsSessionRepository.java:627)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository.access$400(JdbcOperationsSessionRepository.java:129)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository$1$2.setValues(JdbcOperationsSessionRepository.java:403)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:960)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:950)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:662)
    at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:950)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository$1.doInTransactionWithoutResult(JdbcOperationsSessionRepository.java:395)
    at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:34)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository.save(JdbcOperationsSessionRepository.java:377)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository.save(JdbcOperationsSessionRepository.java:129)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217)
    at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170)
    at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
like image 962
brian661 Avatar asked Nov 07 '18 07:11

brian661


1 Answers

Try changing your component to:

@Component
@Scope(value = SCOPE_SESSION, proxyMode = TARGET_CLASS)
public class SessionForm implements Serializable {
    private String someOtherFeild;
    private JsonNode custom;

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        if(custom== null){
            out.writeBoolean(false);
        } else {
            out.writeBoolean(true);
            new ObjectMapper().configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false).writeValue(out, custom);
        }
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        if(in.readBoolean()){
            this.custom = new ObjectMapper().configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false).readValue(in, JsonNode.class);
        }
    }
}

This will change the default serialization, allowing you to override the default behaviour and work around this error

Reference

like image 166
Sven Hakvoort Avatar answered Nov 05 '22 02:11

Sven Hakvoort