簡體   English   中英

在數據庫對象中存在持久性后反序列化無法強制轉換為源類:ClassCastException:TestDomain無法強制轉換為TestDomain

[英]Deserialized after persistence in Database object can't be casted into source Class: ClassCastException: TestDomain cannot be cast to TestDomain

我在spring-session面臨以下問題:

@RestController
public class TestService {

    @Autowired
    private SessionRepository sessionRepository;

    @GetMapping("/test")
    public void test() {
        Session session = sessionRepository.createSession();
        TestDomain testDomain = new TestDomain("a", 1);
        session.setAttribute(session.getId(), testDomain);
        sessionRepository.save(session);

        Session session1 = sessionRepository.getSession(session.getId());
        Object testDomainObj = session1.getAttribute(session1.getId());
        // I wonder why TestDomainObj is not an instance of TestDomain??
        System.out.println("Does testDomainObj from session represent the instance of TestDomain class: " + (testDomainObj instanceof TestDomain));

        // java.lang.ClassCastException: com.example.demo.TestDomain cannot be cast to com.example.demo.TestDomain
        TestDomain testDomain1 = (TestDomain) testDomainObj;
        System.out.println(testDomain1);
    }
}

我嘗試搜索,發現在獲得testDomainObj之后,它是Object類的實例。 因此,很明顯,反序列化的對象會丟失其元信息。

我像這樣配置JdbcOperationsSessionRepository

@Configuration
public class AppConfig {
    @Bean
    SessionRepository sessionFactoryBean(JdbcTemplate jdbcTemplate, PlatformTransactionManager transactionManager) {
        return new JdbcOperationsSessionRepository(jdbcTemplate, transactionManager);
    }
}

並在application.properties激活它:

spring.session.store-type=jdbc
spring.session.jdbc.initializer.enabled=true

執行sessionRepository.save(session);之后,最后一件事testDomain對象已保存在數據庫中sessionRepository.save(session);

如何理解和應對這個問題?

您遇到此問題的原因是您手動注冊了JdbcOperationsSessionRepository bean,而不是重用Spring Session JDBC配置工具,即@EnableJdbcHttpSession 請參見JdbcHttpSessionConfiguration的相關代碼

Spring Boot通過為Spring Session提供自動配置支持而使此操作變得更加容易,因此您甚至不需要使用@EnableJdbcHttpSession 只需將spring.session.store-type=jdbc添加到配置屬性即可為您完成所有工作。

好吧,我回答我的問題。 就我而言,我應該為反序列化器指定ClassLoader,如下所示:

@Bean
SessionRepository sessionFactoryBean(JdbcTemplate jdbcTemplate, PlatformTransactionManager transactionManager) {
    JdbcOperationsSessionRepository sessionRepository = new JdbcOperationsSessionRepository(jdbcTemplate, transactionManager);
    GenericConversionService conversionService = new GenericConversionService();
    conversionService.addConverter(Object.class, byte[].class,
            new SerializingConverter());
    conversionService.addConverter(byte[].class, Object.class,
            new DeserializingConverter(Thread.currentThread().getContextClassLoader()));
    sessionRepository.setConversionService(conversionService);
    return sessionRepository;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM