Lors de l'utilisation de JPA (Hibernate), l'application Java ne se termine pas même si elle atteint la dernière ligne de la méthode main.

En principe, la version d'Hibernate est la 5.3.3. Les dépendances de pom.xml sont les suivantes:

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>

Tout d'abord, préparez le fichier META-INF \ persistence.xml suivant. Le dialecte et le pilote sont Db2, mais ici le type de SGBDR n'a pas d'importance, et si vous choisissez MySQL ou Postgres, par exemple, vous devriez avoir le même problème -.

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>

__ Après cela, lorsque j'ai créé et exécuté la méthode principale suivante, l'application Java ne s'est pas terminée (´ ・ ω ・ `) __ Par exemple, dans eclipse, sélectionnez "Clic droit> Exécuter en tant que> Application Java" et sélectionnez Lorsque vous exécutez la méthode principale, le message "terminé" apparaît après avoir exécuté le contenu dans l'ordre. Cependant, lorsque j'exécute la méthode principale avec cette procédure, il semble que j'ai atteint la dernière ligne de la méthode principale, mais le message "terminé" n'apparaît pas pour toujours. Ou si vous les mettez ensemble dans un fichier jar exécutable et exécutez cette méthode principale, ce processus ne se terminera jamais. A moins que vous ne forciez l'arrêt avec kill -9 etc., vous ne pourrez pas sortir de la méthode principale.

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:Effectuez des opérations sur la base de données.
            transaction.commit();
        } catch (RuntimeException e) {
            if (transaction != null && transaction.isActive()) {
                transaction.rollback();
            }
            throw e;
        }
    }
}

__ Au fait, ce problème "L'application ne se termine pas même si j'ai atteint la dernière ligne de la méthode principale" a été résolu par close ʻEntityManagerFactory`. __ Par exemple, si vous réécrivez la méthode principale comme suit, eclipse affichera «terminé» lorsque la méthode principale se terminera et le fichier exécutable terminera le processus.

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:Effectuez des opérations sur la base de données.
            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();
            }
        }
    }
}

En bref, cela a été causé par l'omission de fermer ʻEntityManagerFactory. En regardant [JavaDoc pour ʻEntityManagerFactory](https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManagerFactory.html), il est dit: "Lorsque l'application a:" fini d'utiliser la fabrique de gestionnaires d'entités et / ou à l'arrêt de l'application, l'application doit fermer la fabrique de gestionnaires d'entités. "Lorsque vous utilisez JavaEE ou Spring, utilisez @ Autowired ou @ Inject pour créer une instance. Fondamentalement, c'est laissé au framework, mais lors du contrôle du cycle de vie de l'instance par lui-même comme dans l'exemple ci-dessus, JPA est notifié que l'application est terminée en appelant ʻEntityManagerFactory # close` lorsque l'application est terminée. Il semble qu'il soit nécessaire de notifier également (´ ・ ω ・ `)

Recommended Posts

Lors de l'utilisation de JPA (Hibernate), l'application Java ne se termine pas même si elle atteint la dernière ligne de la méthode main.
[Java] Traitement de la situation où le programme qui écrit dans le flux de sortie du processus ne se termine pas même si waitFor
Méthode de réglage qui ne change pas la taille même si le CSS est changé
Même si j'écris le paramètre de STRICT_QUOTE_ESCAPING dans CATALINA_OPTS dans tomcat8.5, il n'est pas reflété.
Vérifiez l'état des applications Java sans utiliser d'outils de surveillance
[Firebase] Firebase Auth currentUser ne devient pas nul même après la désinstallation de l'application