Сканирование аннотаций в спящем режиме не работает в Gradle 5.4 - PullRequest
1 голос
/ 25 апреля 2019

Я занят преобразованием сборки maven в сборку Gradle, у меня все работает, кроме того, что теперь я вижу эту ошибку всякий раз, когда я пытаюсь выполнить hql-запрос через Hibernate для всех сущностей, к которым я пытаюсь сделать запрос (работает через 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 использует стандартный плагин Shade:

            <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 для запуска не используется shade / shadow-jarring, поэтому даже если я удаляю jarring shadow / shade, он продолжает демонстрировать то же поведение.

Что-то, что я заметил, было структурой пакета после сборки, у maven есть все под classes, тогда как Gradle разбивает классы на java / kotlin

Maven:

enter image description here

Gradle:

enter image description here

Я не уверен, влияет ли вышеуказанная структура на сканирование аннотаций.

Я пытался добавить <property name="packagesToScan" value="....." /> в файле persistence.xml для каждого затронутого объекта без эффекта.

Все сущности аннотированы правильно (как я уже говорил, это все еще работает правильно в 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 Ответ

1 голос
/ 09 июля 2019

Вы пытались добавить следующее в build.gradle?

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

Цитировать из сообщения в блоге Java - Чего не хватает в gradle для отображения спящего режима? .

И поскольку 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...