[英]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.