Search code examples
hibernatehibernate-mapping

Hibernate Error when autodetecting annotated entity classes


I am using hibernate and I don't want to add every single entity class into the hibernate.cfg.xml but instead let hibernate autodetect my classes.

I read that I can use the two properties hibernate.archive.autodetection and hibernate.packageToScan, but that doesn't work. Instead I get this error: Unable to locate persister: ina.project.backend.entities.UserEntity

Do you know what I did wrong and how to fix it? Thanks in advance! Below you will find my pom.xml, hibernate.cfg.xml (old version and new one) such as the UserEntity.java (The Entity that causes problems).

I am happy to provide more information if necessary!

P.S. Everything works with the old hibernate.cfg.xml

pom.xml:

<?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>

    <groupId>main</groupId>
    <artifactId>InternetAnwendungen-Project</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>
    <name>Internet Anwendung - Project</name>
    <url>https://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.16.1</version>
        </dependency>
        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-web-api</artifactId>
            <version>9.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.2.5.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>7.0.4.Final</version>
        </dependency>
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>3.0.8</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains</groupId>
            <artifactId>annotations</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>io.github.cdimascio</groupId>
            <artifactId>dotenv-java</artifactId>
            <version>2.2.0</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>ROOT</finalName>
        <directory>./dev-ops/build</directory>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
                <configuration>
                    <outputDirectory>./dev-ops/build</outputDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

UserEntity.java:

package ina.project.backend.entities;

import jakarta.persistence.*;
import jakarta.validation.constraints.Size;

import java.io.Serializable;

@Entity
@Table(name = "User")
@NamedQuery(name = "user.byId", query = "SELECT u FROM UserEntity u  where u.id = ?1")
@NamedQuery(name = "user.byUsername", query = "SELECT u FROM UserEntity u  where u.username = ?1")
public class UserEntity implements Serializable {
    @Id
    @Column(name = "id", nullable = false, unique = true, updatable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "username", nullable = false, unique = true)
    @Size(min = 4, max = 100)
    private String username;

    @Column(name = "password", nullable = false)
    private String password;

    public int getId() {
        return id;
    }

    public UserEntity setId(int id) {
        this.id = id;
        return this;
    }

    public String getUsername() {
        return username;
    }

    public UserEntity setUsername(String username) {
        this.username = username;
        return this;
    }

    public String getPassword() {
        return password;
    }

    public UserEntity setPassword(String password) {
        this.password = password;
        return this;
    }
}

hibernate.cfg.xml (old):

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>

        <!-- Connection Properties -->
        <property name="connection.driver_class">org.mariadb.jdbc.Driver</property>

        <property name="connection.pool_size">10</property>
        <property name="dialect">org.hibernate.dialect.MariaDBDialect</property>
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCachingRegionFactory</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">validate</property>
        <property name="current_session_context_class">thread</property>
        <mapping class="ina.project.backend.entities.UserEntity"/>
    </session-factory>

</hibernate-configuration>

hibernate.cfg.xml (new):

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>

        <!-- Connection Properties -->
        <property name="connection.driver_class">org.mariadb.jdbc.Driver</property>

        <property name="connection.pool_size">10</property>
        <property name="dialect">org.hibernate.dialect.MariaDBDialect</property>
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCachingRegionFactory</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">validate</property>
        <property name="current_session_context_class">thread</property>
        <property name="hibernate.archive.autodetection">class, hbm</property>
        <property name="hibernate.packageToScan">ina.project.backend.entities</property>
    </session-factory>

</hibernate-configuration>

Solution

  • packageToScan is a spring feature but not a hibernate property which can be proved from the fact that you cannot find it in AvailableSettings which defines all the properties supported by Hibernate.

    Remember that native hibernate hibernate.cfg.xml does not support such auto entities scanning , and that 's why spring added such support back to the time when it provided integration with Hibernate.