【问题标题】:Spring Boot 2: Duplicate annotation issue when using hibernate-jpamodelgenSpring Boot 2:使用 hibernate-jpamodelgen 时出现重复注释问题
【发布时间】:2018-10-28 05:44:03
【问题描述】:

我有一个使用 hibernate-jpamodelgen 的简单 Spring Boot 2 应用程序。这是整个 Maven POM:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>

      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
      </parent>

      <groupId>gov.idaho.isp</groupId>
      <artifactId>SpringBootJpaModelGenIssue</artifactId>
      <version>0.1</version>  
      <packaging>jar</packaging>

      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <tomcat.version>9.0.5</tomcat.version>
        <java.version>1.8</java.version>
      </properties>

      <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-devtools</artifactId>
          <optional>true</optional>
        </dependency>

        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId>
        </dependency>

        <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-jpamodelgen</artifactId>
        </dependency>
      </dependencies>

    </project>

应用程序包含一个简单的实体,Widget 有一个@NotNull java bean 验证约束注解:

    import java.io.Serializable;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.validation.constraints.NotNull;

    @Entity
    public class Widget implements Serializable {
      @Id @GeneratedValue
      private Long id;

      @NotNull
      private String name;
      ...
    }

当运行这个Spring Boot应用程序,然后对该实体进行更改时,应用程序由于错误而未能成功重启:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.cfg.beanvalidation.IntegrationException: Error activating Bean Validation integration

最终的根本原因是:

Caused by: java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface javax.validation.constraints.NotNull: @javax.validation.constraints.NotNull(message={javax.validation.constraints.NotNull.message}, groups=[], payload=[])

如果删除了 hibernate-jpamodelgen 依赖项,则此重新启动错误将消失。这是一个已知问题吗?

请参阅https://github.com/BriceRoncace/SpringBootJpaModelGenIssue 的示例应用程序以重新创建问题。 (我在 Spring Boot 2.0.0 和 2.0.2 中遇到过这个问题。)

【问题讨论】:

  • 我认为您需要从 hibernate-jpamodelgen 中排除 javax.validation.constraints 包
  • 有没有“spring boot”的惯用方式来做到这一点?
  • 这将是一个传统的 maven 依赖排除 pom 中的元素。
  • 我不确定我是否遵循。当我查看 maven 依赖项:树时,我看到 hibernate-jpamodelgen 的唯一传递依赖项是在 jboss-logging 上。你能澄清一下你的意思吗?

标签: spring-boot spring-data-jpa bean-validation


【解决方案1】:

一种解决方法是使用maven-processor-plugin 明确指定org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor 应该执行并将hibernate-jpamodelgen 依赖项移动到插件定义中:

<plugin>
  <groupId>org.bsc.maven</groupId>
  <artifactId>maven-processor-plugin</artifactId>
  <version>3.3.3</version>
  <executions>
    <execution>
      <id>process</id>
      <goals>
        <goal>process</goal>
      </goals>
      <phase>generate-sources</phase>
      <configuration>
        <processors>                                
          <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
        </processors>
      </configuration>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-jpamodelgen</artifactId>
      <version>5.2.17.Final</version>
    </dependency>
  </dependencies>
</plugin>

hibernate 元模型文档表明您应该禁用编译器插件的注释处理:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <compilerArgument>-proc:none</compilerArgument>
  </configuration>
</plugin>

但是我发现即使不禁用编译器注解处理,上面报的spring boot重启错误也消失了。

查看提交https://github.com/BriceRoncace/SpringBootJpaModelGenIssue/commit/033ba0078b519d188e7d4c0e6ec66f4278d50ab1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-19
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    相关资源
    最近更新 更多