Hibernate注释扫描在Gradle 5.4下不起作用

时间:2019-04-25 07:21:53

标签: java hibernate maven gradle kotlin

我正忙于将Maven构建转换为Gradle构建,所有操作都在运行,除了我现在每次尝试通过Hibernate为我尝试查询的所有实体运行hql查询(通过Maven运行)时都会看到此错误仍然有效,但pom文件仍在项目中):

org.hibernate.hql.internal.ast.QuerySyntaxException: Account is not mapped [SELECT o FROM Account AS o WHERE lower(o.email)=:email]

我在Maven下具有以下依赖关系:

    <dependencies>

        ...

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>cglib</groupId>
                    <artifactId>cglib</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>dom4j</groupId>
                    <artifactId>dom4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>${hibernate-validator.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-java8</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        ...

</dependencies>

在Gradle(Kotlin DSL)下,它看起来很相似(尽管更短):

dependencies {

    ...

    // hibernate
    val hibernateVersion = "5.2.13.Final"
    implementation(group = "org.hibernate", name = "hibernate-core", version = hibernateVersion)
    implementation(group = "org.hibernate", name = "hibernate-entitymanager", version = hibernateVersion).
        exclude(group = "cglib", module = "cglib").
        exclude(group = "dom4j", module = "dom4j")
    implementation(group = "org.hibernate", name = "hibernate-validator", version = hibernateVersion)
    implementation(group = "org.hibernate", name = "hibernate-c3p0", version = hibernateVersion)
    implementation(group = "org.hibernate", name = "hibernate-java8", version = hibernateVersion)

    ...

}

Persistence.xml非常标准:

<persistence-unit name="default">
        <description>Persistence XML</description>
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>

            <!-- Hibernate Config -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL95Dialect" />
            <property name="hibernate.generate_statistics" value="false" />

            <property name="hibernate.hbm2ddl.auto" value="validate"/>

            <property name="hibernate.physical_naming_strategy" value="com.application.util.CustomNamingStrategy"/>

            <property name="hibernate.connection.charSet" value="UTF-8"/>
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value="false"/>
            <property name="hibernate.use_sql_comments" value="false"/>

            <!-- JDBC Config -->
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />

            <property name="javax.persistence.jdbc.time_zone" value="UTC" />
            <property name="hibernate.jdbc.time_zone" value="UTC"/>

            <!-- Connection Pool -->
            <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
            <property name="hibernate.c3p0.max_size" value="5" />
            <property name="hibernate.c3p0.min_size" value="1" />
            <property name="hibernate.c3p0.acquire_increment" value="1" />
            <property name="hibernate.c3p0.idle_test_period" value="300" />
            <property name="hibernate.c3p0.max_statements" value="0" />
            <property name="hibernate.c3p0.timeout" value="100" />

            <!-- Batch writing -->
            <property name="hibernate.jdbc.batch_size" value = "50"/>
            <!-- if this is switched on fixtures does not want to run for some or other reason -->
            <!--<property name="hibernate.order_inserts" value = "true"/>-->
            <property name="hibernate.order_updates" value = "true"/>
            <property name="hibernate.jdbc.batch_versioned_data" value = "true"/>

        </properties>
    </persistence-unit>

Maven使用标准的阴影插件:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <manifestEntries>
                                        <Main-Class>ApplicationApi</Main-Class>
                                    </manifestEntries>
                                </transformer>
                            </transformers>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                        <exclude>junit:junit</exclude>
                                        <exclude>rebel.xml</exclude>
                                        <exclude>org.apache.maven:lib:tests</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <artifactSet/>
                            <shadedArtifactAttached>true</shadedArtifactAttached>
                            <shadedClassifierName>standalone</shadedClassifierName>
                            <outputFile>${project.build.directory}/api.jar</outputFile>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Gradle使用shadowJar插件:

plugins {
    ...
    id("com.github.johnrengelman.shadow").version("5.0.0")
    ...
}

尽管从IntelliJ运行不会使用阴影/阴影震荡来运行,所以即使我删除了阴影/阴影震荡,它仍会表现出相同的行为。

我确实注意到的是构建后的包结构,maven在classes下拥有所有内容,而Gradle将类拆分为java / kotlin

行家:

enter image description here

等级:

enter image description here

我不确定上述结构是否会对注释扫描产生任何影响。

我尝试在persistence.xml中为每个受影响的实体添加<property name="packagesToScan" value="....." />,但无效。

所有实体都正确注释(正如我提到的那样,它仍然可以在Maven下正常运行)

@Entity
@Table
@PersistenceContext(unitName = "default")
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@BatchSize(size = 50)
class Account(
    email: String,
    ...

有人知道为什么我切换到Gradle后会收到此错误吗?

org.hibernate.hql.internal.ast.QuerySyntaxException: Account is not mapped [SELECT o FROM Account AS o WHERE lower(o.email)=:email]
    at org.hibernate.internal.ExceptionConverterImpl.convert (ExceptionConverterImpl.java:133)
    at org.hibernate.internal.ExceptionConverterImpl.convert (ExceptionConverterImpl.java:157)
    at org.hibernate.internal.ExceptionConverterImpl.convert (ExceptionConverterImpl.java:164)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery (AbstractSharedSessionContract.java:670)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery (AbstractSharedSessionContract.java:686)
    at org.hibernate.internal.AbstractSessionImpl.createQuery (AbstractSessionImpl.java:23)

1 个答案:

答案 0 :(得分:1)

您是否尝试过在build.gradle上添加以下内容?

sourceSets {
  java {
    main {
      output.resourcesDir = java.outputDir
    }
  }
}

引用Java - What is gradle missing to map hibernate?的博客文章。

  

并且由于Gradle不会将“已编译”资源与已编译类存储在同一输出目录中,因此Hibernate找不到映射的实体。

这就是您需要添加以上配置的原因。 同样,从Gradle 5.x中撤消了sourceSets.main.output.classesDir,该配置中提到了许多博客文章。因此,您需要像上面一样使用sourceSets.main.java.outputDir

另请参阅:SourceSetOutput-Gradle DSL版本5.5 https://docs.gradle.org/current/dsl/org.gradle.api.tasks.SourceSetOutput.html