0

I'm using Hibernate in my Java SE program, so no application server.

I'm using my persistence manager:

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

public enum PersistenceManager {
    INSTANCE;

    private EntityManagerFactory emFactory;

    private PersistenceManager() {
        emFactory = Persistence.createEntityManagerFactory("jpa-example");
    }

    public EntityManager getEntityManager() {
        return emFactory.createEntityManager();
    }

    public void close() {
        emFactory.close();
    }

}

with a very simple persistence.xml:

<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="jpa-example" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/mydb?useSSL=false" />
            <property name="javax.persistence.jdbc.user" value="myuser" />
            <property name="javax.persistence.jdbc.password" value="password" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        </properties>
    </persistence-unit>
</persistence>

My functional code:

        EntityManager em = PersistenceManager.INSTANCE.getEntityManager();
        em.getTransaction().begin();

        // dummy object instantiation here
        em.persist(obj1);
        em.persist(obj2);
        em.getTransaction().commit();
        System.out.println("comitting");
        em.close();
        System.out.println("closed");
        PersistenceManager.INSTANCE.close();
        System.out.println("Done");

My application does print everything as expected, i.e. "closed" and "done" appear in my console. I also see in my mysql container that the transaction went fine. However, the program never terminates and ends in exception:

[WARNING] thread Thread[Abandoned connection cleanup thread,5,com.org.Main] was interrupted but is still alive after waiting at least 15000msecs
[WARNING] thread Thread[Abandoned connection cleanup thread,5,com.org.Main] will linger despite being asked to die via interruption
[WARNING] NOTE: 1 thread(s) did not finish despite being asked to  via interruption. This is not a problem with exec:java, it is a problem with the running code. Although not serious, it should be remedied.
[WARNING] Couldn't destroy threadgroup org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=com.org.Main,maxpri=10]
java.lang.IllegalThreadStateException
    at java.lang.ThreadGroup.destroy (ThreadGroup.java:778)
    at org.codehaus.mojo.exec.ExecJavaMojo.execute (ExecJavaMojo.java:321)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:134)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:309)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:194)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:107)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:955)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:290)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:194)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)

Why is that? What am I doing incorrectly? It seems like there's some non-blocking call to close, which takes time but the program wants to terminate.

halpdoge
  • 642
  • 7
  • 19

1 Answers1

1

You seems to run in the same issue that this post https://stackoverflow.com/a/29987290/10691359. He solved his problem with a

-Dexec.cleanupDaemonThreads=false

Your problem has nothing to do with Hibernate.

Another solution here https://stackoverflow.com/a/45470078/10691359 is to use System.exit(0) at the end of your main.

Pilpo
  • 1,236
  • 1
  • 7
  • 18
  • Thank you, you're absolutely right. I did not see the other question, but is definitely a duplicate. A shame that nobody explained why this happens; it's possible it has something to do with maven itself – halpdoge May 04 '19 at 17:23
  • You're welcome. Yes it is very odd, and the only documentation I found state that "_cleanupDaemonThreads:Whether to interrupt/join and possibly stop the daemon threads upon quitting. If this is false, maven does nothing about the daemon threads. When maven has no more work to do, the VM will normally terminate any remaining daemon threads_". So it seems that when this is option is equal "true" maven try to stop some threads by itself instead of letting the VM doing its job. Even with that documentation, it is not very clear to me either... why would maven try to stop the VM threads? A mystery. – Pilpo May 04 '19 at 17:31