I am trying to get hibernate working with glassfish 7 jdbc. I got the configuration of the pool right and ping is a success. I have put mysql-connector-j-8.0.33.jar and hibernate-core-6.2.6.Final.jar in glassfish/domain/domain1/lib. My persistence.xml looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
version="3.0">
<persistence-unit name="persistence-unit">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jpa1</jta-data-source>
<class>jpa1.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
<!--
<persistence-unit name="persistence-unit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:8889/learn_it_jpa?autoReconnect=true&useSSL=false"/>
<property name="jakarta.persistence.jdbc.user" value="root"/>
<property name="jakarta.persistence.jdbc.password" value="root"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="jakarta.persistence.schema-generation.database.action" value="none"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
</properties>
</persistence-unit>
-->
</persistence>
When I am trying to use hibernate with resource_local there is no error. But when I try to use the jdbc persistence-unit im getting following error:
java.lang.NoClassDefFoundError: org/hibernate/annotations/common/reflection/ReflectionManager
I have added hibernate-core-6.2.6.Final.jar in the lib folder of glassfishs domain but i still getting noclassfounderror. With the resource_local persistence-unit i dont get that error. I understand that its possible to add further jar files in the lib folder to solve this problem but i might doing something wrong because the hibernate-core was working with the resource_local persistence-unit.
My pom file
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>jpa1</artifactId>
<packaging>war</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<version>1.0-SNAPSHOT</version>
<name>jpa1 Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.2.6.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>jpa1</finalName>
</build>
</project>
The code where I am using jpa
package jpa1;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet(name = "homeServlet", value = "/start")
public class HomeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence-unit");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
User user1 = new User("Max","Mustermann", User.Gender.MALE, 10, 50000, 1000);
entityManager.persist(user1);
entityManager.getTransaction().commit();
List<User> results = entityManager
.createQuery("Select a from User a", User.class)
.getResultList();
entityManager.close();
entityManagerFactory.close();
req.setAttribute("test", results);
req.getRequestDispatcher("start.jsp").forward(req, resp);
}
}
The entity:
package jpa1;
import jakarta.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "gender")
@Enumerated(EnumType.ORDINAL)
private Gender gender;
@Column(name = "age")
private int age;
@Column(name = "salary")
private int salary;
@Column(name = "test")
private int test;
public User() {
}
public enum Gender {
MALE,
FEMALE
}
public User(String firstName, String lastName, Gender gender, int age, int salary, int test) {
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
this.age = age;
this.salary = salary;
this.test = test;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public Gender getGender() {
return gender;
}
public String getGenderStr() {
switch (gender) {
case MALE -> {
return "Männlich";
}
case FEMALE -> {
return "Weiblich";
}
default -> {
return "";
}
}
}
public int getAge() {
return age;
}
}
What I am using:
I have added now the following jars in the glassfish/domain/domain/lib folder to add the missing classes needed for hibernate:
With that all missing classes are added but after the first successful using the entitymanager the next refresh of the page theres an endless loop loading.
When i stop the server the following error message appears:
Error allocating connection: [org.glassfish.resourcebase.resources.api.PoolInfo@f6def2b2[jndiName=test/jpa1, applicationName=null, moduleName=null]: No Pool Meta Data object associated with the pool : org.glassfish.resourcebase.resources.api.PoolInfo@f6def2b2[jndiName=test/jpa1, applicationName=null, moduleName=null]. Try redeploying the application.]]]
SQL Error: 0, SQLState: null]]
I found for sql error 0, sqlstate null a post SQL Error: 0, SQLState: null
The problem was that the EntityManagerFactory was closed and the connection was lost. When i not close the factory the connection will be established as long as the app runs. Thats how i solved it:
package jpa1;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet(name = "homeServlet", value = "/start")
public class HomeServlet extends HttpServlet {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence-unit");
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
User user1 = new User("Max","Mustermann", User.Gender.MALE, 10, 50000, 1000);
entityManager.persist(user1);
entityManager.getTransaction().commit();
List<User> results = entityManager
.createQuery("Select a from User a", User.class)
.getResultList();
entityManager.close();
req.setAttribute("test", results);
req.getRequestDispatcher("start.jsp").forward(req, resp);
}
}
EDIT: This only works when you always restart the server. If you redeploy it the endless loading loop continues.
EDIT 2: After putting the EntityManagerFactory out of the servlet class into a seperate class and make it static theres no loop.
Globals class:
public class Globals {
public static EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence-unit");
}