Hibernate 5 和 Spring Boot 2 - 多次注册的 AttributeConverter 类

标签 hibernate spring-boot intellij-idea hibernate-5.x

在我的 Spring Boot 应用程序中,我有一个简单的 JPA AttributeConverter 声明如下:

@Converter(autoApply = true)
public class GenderConverter implements AttributeConverter<Gender, String> {...}

并像这样应用:

@Entity
public class User {
    @Column(length = 1, nullable = false)
    private Gender gender;
    // ...
}

如果我使用 IntelliJ IDEA 运行/调试配置来启动 Spring Boot 应用程序,上下文初始化会因 AssertionFailure 异常而失败。如果我使用 gradle clean bootRun 应用程序成功启动。所以它看起来像是IDE中的错误或项目设置错误。

我调试并转储了 Converter 的两个后续注册的堆栈跟踪,但我仍然不明白为什么它会发生两次。请分析堆栈跟踪。

第一次注册(没有报错):

  at org.hibernate.boot.internal.AttributeConverterManager.addConverter(AttributeConverterManager.java:44)
  at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.addAttributeConverter(InFlightMetadataCollectorImpl.java:353)
  at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)
  at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:861)
  at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888)
  at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57)
  at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
  at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390)
  at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377)
  at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
  at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
  at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$122.379121284.getObject(Unknown Source:-1)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
....

第二次注册(报错!):

Caused by: org.hibernate.AssertionFailure: AttributeConverter class [class by.naxa.example.conversion.GenderConverter] registered multiple times
    at org.hibernate.boot.internal.AttributeConverterManager.addConverter(AttributeConverterManager.java:46) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.addAttributeConverter(InFlightMetadataCollectorImpl.java:353) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.addAttributeConverter(InFlightMetadataCollectorImpl.java:363) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl$AttributeConverterManager.addAttributeConverter(AnnotationMetadataSourceProcessorImpl.java:325) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.categorizeAnnotatedClass(AnnotationMetadataSourceProcessorImpl.java:118) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.<init>(AnnotationMetadataSourceProcessorImpl.java:105) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.<init>(MetadataBuildingProcess.java:147) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:141) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:861) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    ....

如果您认为这可能有帮助,我可以包括 gradle :dependencyInsight --dependency jpa 输出或我的项目结构 > 模块的屏幕截图。

我知道有 a similar question但公认的解决方案对我没有帮助。我不使用 @EnableAutoconfiguration 注释。我的主课很简单:

@SpringBootApplication
public class MysqlApplication {
    public static void main(String[] args) {
        SpringApplication.run(MysqlApplication.class, args);
    }
}

最佳答案

这似乎是 IntelliJ IDEA 和 Spring Boot 的问题 Dev Tools .以下步骤帮助我在 Ubuntu 中解决了这个问题,但在 Windows 10 中没有。

  1. 从 build.gradle 中移除 devtools 依赖:
    // runtimeClasspath group: 'org.springframework.boot', name: 'spring-boot-devtools'
  1. 构建 > 清理项目

  2. 关闭 IntelliJ IDEA:

    文件 > 退出

  3. 执行gradle clean

  4. 从项目根文件夹中删除文件夹:build、out、.gradle:

    rm -rf build out .gradle
  1. 清理系统缓存:

    启动 IntelliJ IDEA 并转到菜单文件 > 使缓存无效/重新启动

  2. 等待 IntelliJ 更新索引

现在尝试再次运行调试配置。重建项目需要一段时间,但随后应该会成功启动。

关于Hibernate 5 和 Spring Boot 2 - 多次注册的 AttributeConverter 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52822568/

相关文章:

spring-boot - 使用 Spring Boot 将依赖注入(inject)到 Logback Appenders

java - 如何在 Android Studio 中使用暂存文件?

Java 应用程序在 IDE 之外无法正常工作

java - HQL 嵌套子查询

hibernate - Grails独特的约束

eclipse - Eclipse 中的 "mvn spring-boot:run"和 "Add to Tomcat server"有什么区别?

java - Amazon Kinesis + 集成测试

scala - IntelliJ Scala配置问题

java - Spring Boot - Web 应用程序无法停止 MVStore 编写器线程

hibernate - 包含自身的 Grails 域类