Spring Boot 上下文中的 Jooq CastException 已刷新

Posted

技术标签:

【中文标题】Spring Boot 上下文中的 Jooq CastException 已刷新【英文标题】:Jooq CastException on Spring Boot context refreshed 【发布时间】:2018-10-04 03:21:11 【问题描述】:

spring boot 首次启动时,jooq 运行良好。 但是如果我对代码进行更改并且在春季启动上下文刷新后, 然后我遇到了类转换异常的麻烦。 问题是同一类的强制转换异常。

我的启动配置是:

@Autowired
private DataSource dataSource;
public ExecuteListener exceptionTransformer() 
    return new DefaultExecuteListener() 
        private static final long serialVersionUID = 1L;
        @Override
        public void exception(ExecuteContext context) 
            SQLDialect dialect = context.configuration().dialect();
            SQLExceptionTranslator translator = (dialect != null)
                ? new SQLErrorCodeSQLExceptionTranslator(dialect.name())
                : new SQLStateSQLExceptionTranslator();
            context.exception(
                translator.translate("jOOQ", context.sql(), context.sqlException()));
        
    ;

@Primary
@Bean
public DefaultDSLContext dsl() 
    return new DefaultDSLContext(configuration());

public DataSourceConnectionProvider connectionProvider() 
    return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));

public DefaultConfiguration configuration() 
    DefaultConfiguration configuration = new DefaultConfiguration();
    configuration.set(connectionProvider());
    configuration.set(new DefaultExecuteListenerProvider(exceptionTransformer()));
    configuration.set(SQLDialect.mysql);
    // @formatter:off
    configuration.set(
        new Settings()
        .withExecuteLogging(true)
        .withRenderFormatted(true)
        );
    // @formatter:on
    configuration.set(SfmRecordMapperProviderFactory.newInstance().ignorePropertyNotFound().newProvider());
    return configuration;

查询代码是:

User user = dsl.select()
    .from(USER)
    .where(USER.USER_ID.eq(id)).fetchOneInto(User.class);

admin.domain.User 是:

@Data
public class User implements Serializable 
    private static final long serialVersionUID = 1L;

    private String userId;
    @JsonIgnore
    private String pswd;
    private String name;
    private String useYn;
    private Timestamp registDatetime;
    private Timestamp updateDatetime;

堆栈跟踪是:

java.lang.ClassCastException: admin.domain.User cannot be cast to admin.domain.User
    at admin.dao.UserDao.getUserByIdWithRoles(UserDao.java:123)
    at admin.dao.UserDao$$FastClassBySpringCGLIB$$f7b71f39.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

我的错是什么?

【问题讨论】:

显然,这似乎是一个类加载问题。我怀疑您的 change the code 操作涉及重新生成一些 jOOQ 生成的类。您能否描述一下这种重新生成是如何发生的,以及您究竟是如何刷新 Spring Boot 上下文的? @Lukas Eder 你的代码给了我很多点击! @LukasEder 对 CL 的看法是正确的。如果同一个类是由不同的类加载器加载的,那么它就不是同一个类。创建 admin.domain.User(jooq?)的类正在使用一个 CL,而 DAO 本身由另一个加载。其中一个丢失并在重新加载时重新创建,而另一个则没有。 【参考方案1】:

您是否启用了 spring boot 自动重启?

这个样子,你可以试试:

无需开发工具即可运行 (https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-restart-disable) 为您的实时重新加载添加正确的路径( https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-restart-additional-paths 和 https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-customizing-classload )

:)

【讨论】:

那你不再使用spring boot自动重启了,所以很可能是罪魁祸首。 不!我只想让我的团队通过 jooq 远离 mybatis。 不!我只想让我的团队通过 jooq 远离 mybatis。我第一次建议 JPA,但我的团队抱怨我 JPA。所以接下来我搜索 jooq。我测试了它的可用性。我对jooq很满意。但是我的团队需要在开发环境中重新启动稳定性。当我陷入演员阵容问题时,我无法及时解决它。我没有太多时间来解决它,但我希望我的团队继续前进。所以接下来我的建议是jrebel。我没有放弃,只是需要更多的时间。感谢您的关注。我英语不好,但你可能知道我的意图。

以上是关于Spring Boot 上下文中的 Jooq CastException 已刷新的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring-Boot config 配置 JOOQ 设置?

jooQ spring boot Multiple Schema(读写拆分)

Spring Boot with JOOQ 和 Spring Data JPA 之间的技术差异

使用 Spring Boot 进行 JOOQ SQL 语法转换

带有 JOOQ 的 Spring Boot 收到一条消息“需要一个找不到的 'org.jooq.DSLContext' 类型的 bean”

Spring boot、JOOQ和Flyway如何一起使用?