When using JPA (Hibernate), the Java application does not end even if it reaches the last line of the main method.

As a premise, the version of Hibernate is 5.3.3. The dependencies in pom.xml are as follows:

pom.xml


<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>5.3.3.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.0</version>
</dependency>

First, prepare the following META-INF \ persistence.xml. The dialect and driver are Db2, but here the RDBMS type doesn't matter, and if you choose MySQL or Postgres, for example, you should have the same problem--.

persistence.xml


<?xml version="1.0" encoding="UTF-8"?>

<persistence
  xmlns="http://xmlns.jcp.org/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  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="app">
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect" />
      <property name="hibernate.connection.driver_class" value="com.ibm.db2.jcc.DB2Driver" />
      <property name="hibernate.connection.url" value="jdbc:db2://[url]:[port]/[DBNAME]" />
      <property name="hibernate.connection.username" value="[user name]" />
      <property name="hibernate.connection.password" value="[password]" />
      <property name="hibernate.show_sql" value="true" />
    </properties>
  </persistence-unit>
</persistence>

__ After that, when I created and executed the following main method, the Java application did not end (´ ・ ω ・ `) __ For example, in eclipse, select "Right click> Run As> Java Application" and select When you execute the main method, the message "terminated" will appear after executing the contents in order. However, when I execute the main method with this procedure, it seems that I have reached the last line of the main method, but the message "terminated" does not appear forever. Or if you put them in an executable jar and execute this main method, this process will never end. Unless you kill it with kill -9 etc., you will not be able to get out of the main method.

Main.java


import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class Main {
    public static void main(String[] args) {
        EntityManagerFactory factory = null;
        EntityManager manager = null;
        EntityTransaction transaction = null;
        
        try {
            factory = Persistence.createEntityManagerFactory("app");
            manager = factory.createEntityManager();
            transaction = manager.getTransaction();
            
            transaction.begin();            
            // DO SOMETHING:Perform operations on the DB.
            transaction.commit();
        } catch (RuntimeException e) {
            if (transaction != null && transaction.isActive()) {
                transaction.rollback();
            }
            throw e;
        }
    }
}

__ By the way, this problem "The application does not end even though I have reached the last line of the main method" was solved by close ʻEntityManagerFactory`. __ For example, if you rewrite the main method as follows, eclipse will display "terminated" when the main method ends, and the executable jar will complete the process.

Main.java


import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class Main {
    public static void main(String[] args) {
        EntityManagerFactory factory = null;
        EntityManager manager = null;
        EntityTransaction transaction = null;
        
        try {
            factory = Persistence.createEntityManagerFactory("app");
            manager = factory.createEntityManager();
            transaction = manager.getTransaction();
            
            transaction.begin();
            // DO SOMETHING:Perform operations on the DB.
            transaction.commit();
        } catch (RuntimeException e) {
            if (transaction != null && transaction.isActive()) {
                transaction.rollback();
            }
            throw e;
        } finally {
            if (manager != null) {
                manager.close();
            }
            if (factory != null) {
                factory.close();
            }
        }
    }
}

In short, it was caused by the omission of closing ʻEntityManagerFactory. Looking at the JavaDoc for ʻEntityManagerFactory (https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManagerFactory.html), it says: "When the application has:" finished using the entity manager factory, and / or at application shutdown, the application should close the entity manager factory. "When using JavaEE or Spring, use @ Autowired or @ Inject to create an instance. Basically, it's all left to the framework, but if you control the life cycle of the instance yourself as in the above example, call ʻEntityManagerFactory # close` when the application terminates and let JPA complete the application. It seems that it is necessary to notify also (´ ・ ω ・ `)

Recommended Posts

When using JPA (Hibernate), the Java application does not end even if it reaches the last line of the main method.
[Java] Dealing with the situation where the program that writes to the Output Stream of Process does not end even if waitFor
Setting method that the size does not change even if CSS is changed
Even if I write the setting of STRICT_QUOTE_ESCAPING in CATALINA_OPTS in tomcat8.5, it is not reflected.
Check the status of Java application without using monitoring tool
[Firebase] The problem that the currentUser of Firebase Auth does not become null even if the app is uninstalled.