I used hibernate EntityManager on standalone application (Without framework) .
this is my pom.xml
:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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>ir.moke.roboexchange</groupId>
<artifactId>roboexchange</artifactId>
<version>1.0-SNAPSHOT</version>
<organization>
<name>Moke</name>
<url>http://www.moke.ir</url>
</organization>
<name>Moke :: RoboExchange</name>
<properties>
<junit.jupiter.version>5.9.2</junit.jupiter.version>
<junit.platform.version>1.9.2</junit.platform.version>
</properties>
<packaging>jar</packaging>
<dependencies>
<!-- ORM -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-ant</artifactId>
<version>6.6.0.Final</version>
</dependency>
<!-- Json -->
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>3.0.2</version>
</dependency>
<!-- Database -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.4</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>
<!-- Log -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.6</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite</artifactId>
<version>${junit.platform.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>roboexchange</finalName>
<plugins>
<!-- Java compiler version -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
<!-- copy compiled jar file to target/lib -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>ir.moke.roboexchange.MainClass</mainClass>
</manifest>
</archive>
<outputDirectory>${project.build.directory}/lib/</outputDirectory>
</configuration>
</plugin>
<!-- Copy dependencies -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includeScope>compile</includeScope>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
and this is my persistence.xml
:
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="db-connection" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
</persistence-unit>
</persistence>
I have a class named EntityManagerProducer
:
import ir.moke.roboexchange.config.Configuration;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import java.util.HashMap;
import java.util.Map;
public class EntityManagerProducer {
public static final EntityManagerProducer instance = new EntityManagerProducer();
private final EntityManagerFactory entityManagerFactory;
private final EntityManager entityManager;
private EntityManagerProducer() {
String hostname = Configuration.dbHost;
String port = Configuration.dbPort;
String username = Configuration.dbUsername;
String password = Configuration.dbPassword;
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.connection.driver_class", "org.postgresql.Driver");
properties.put("hibernate.connection.url", "jdbc:postgresql://%s:%s/roboexchange".formatted(hostname, port));
properties.put("hibernate.connection.username", username);
properties.put("hibernate.connection.password", password);
properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
this.entityManagerFactory = Persistence.createEntityManagerFactory("db-connection", properties);
this.entityManager = this.entityManagerFactory.createEntityManager();
}
public EntityManager getEntityManager() {
return entityManager;
}
public EntityManagerFactory getEntityManagerFactory() {
return entityManagerFactory;
}
}
this is my example CRUD :
public class SampleCRUD {
private static final EntityManager em = EntityManagerProducer.instance.getEntityManager();
public static void insert(Sample sample) {
EntityTransaction transaction = em.getTransaction();
transaction.begin();
em.persist(sample);
transaction.commit();
}
}
but when i export project as jar file and run that , result this exception :
Aug 22, 2024 8:40:24 PM jakarta.persistence.spi.PersistenceProviderResolverHolder$DefaultPersistenceProviderResolver log
WARNING: jakarta.persistence.spi::No valid providers found.
Exception in thread "Timer-0" java.lang.ExceptionInInitializerError
at ir.moke.roboexchange.strategy.StrategyManager.<clinit>(StrategyManager.java:22)
at ir.moke.roboexchange.job.FetchStatistics_5Min.run(FetchStatistics_5Min.java:20)
at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
at java.base/java.util.TimerThread.run(Timer.java:516)
Caused by: jakarta.persistence.PersistenceException: No Persistence provider for EntityManager named db-connection
at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:86)
at ir.moke.roboexchange.producer.EntityManagerProducer.<init>(EntityManagerProducer.java:28)
at ir.moke.roboexchange.producer.EntityManagerProducer.<clinit>(EntityManagerProducer.java:12)
... 4 more
Note : persistence.xml
inside jar file is under META-INF
directory
Note : I mixed persistence.xml
and programmatically class, because configuration dynamically maybe changed.
Run application :
> mvn clean compile package
> cd target/lib
> java -jar roboexchange.jar
11:12:21,734 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
11:12:21,769 |-WARN in ch.qos.logback.core.ConsoleAppender[CONSOLE] - This appender no longer admits a layout as a sub-component, set an encoder instead.
11:12:21,769 |-WARN in ch.qos.logback.core.ConsoleAppender[CONSOLE] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
11:12:21,769 |-WARN in ch.qos.logback.core.ConsoleAppender[CONSOLE] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
11:12:21,769 |-WARN in ch.qos.logback.core.model.processor.AppenderModelHandler - Appender named [FILE-ROLLING] not referenced. Skipping further processing.
11:12:21,770 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [org.hibernate] to INFO
11:12:21,774 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [org.hibernate] to false
11:12:21,775 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [CONSOLE] to Logger[org.hibernate]
11:12:21,775 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [ir.moke.roboexchange] to DEBUG
11:12:21,775 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [ir.moke.roboexchange] to false
11:12:21,775 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [CONSOLE] to Logger[ir.moke.roboexchange]
11:12:21,775 |-INFO in ch.qos.logback.classic.model.processor.RootLoggerModelHandler - Setting level of ROOT logger to ALL
11:12:21,776 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [CONSOLE] to Logger[ROOT]
11:12:21,776 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@33cb5951 - End of configuration.
11:12:21,776 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@365c30cc - Registering current configuration as safe fallback point
...
...
...
...... and other logs .....
...
...
Aug 22, 2024 8:40:24 PM jakarta.persistence.spi.PersistenceProviderResolverHolder$DefaultPersistenceProviderResolver log
WARNING: jakarta.persistence.spi::No valid providers found.
Exception in thread "Timer-0" java.lang.ExceptionInInitializerError
at ir.moke.roboexchange.strategy.StrategyManager.<clinit>(StrategyManager.java:22)
at ir.moke.roboexchange.job.FetchStatistics_5Min.run(FetchStatistics_5Min.java:20)
at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
at java.base/java.util.TimerThread.run(Timer.java:516)
Caused by: jakarta.persistence.PersistenceException: No Persistence provider for EntityManager named db-connection
at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:86)
at ir.moke.roboexchange.producer.EntityManagerProducer.<init>(EntityManagerProducer.java:28)
at ir.moke.roboexchange.producer.EntityManagerProducer.<clinit>(EntityManagerProducer.java:12)
... 4 more
this is content of MANIFEST.MF inside jar file :
Manifest-Version: 1.0
Created-By: Maven JAR Plugin 3.2.2
Build-Jdk-Spec: 21
Class-Path: hibernate-core-6.6.0.Final.jar jakarta.persistence-api-3.1.0
.jar jakarta.transaction-api-2.0.1.jar jboss-logging-3.5.0.Final.jar hi
bernate-commons-annotations-7.0.1.Final.jar jandex-3.2.0.jar classmate-
1.5.1.jar byte-buddy-1.14.18.jar jakarta.xml.bind-api-4.0.0.jar jakarta
.activation-api-2.1.0.jar jaxb-runtime-4.0.2.jar jaxb-core-4.0.2.jar an
gus-activation-2.0.0.jar txw2-4.0.2.jar istack-commons-runtime-4.1.1.ja
r jakarta.inject-api-2.0.1.jar antlr4-runtime-4.13.0.jar hibernate-ant-
6.6.0.Final.jar yasson-3.0.2.jar jakarta.json.bind-api-3.0.0.jar jakart
a.json-api-2.1.0.jar parsson-1.1.0.jar postgresql-42.5.4.jar checker-qu
al-3.5.0.jar jedis-4.3.1.jar commons-pool2-2.11.1.jar json-20220320.jar
gson-2.8.9.jar slf4j-api-2.0.5.jar logback-classic-1.4.6.jar logback-c
ore-1.4.6.jar
Main-Class: ir.moke.roboexchange.MainClass
I finally fixed my problem .
maven-dependency-plugin
should be configured like this :
<!-- Copy dependencies -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
Note: Should config to copy runtime
dependencies