I created a program using Hibernate.
The program reaches the main function end, nevertheless the program is running.
I wonder if it happens when SessionFactory
is configured using Hibernate Version 4.x.
Is the way to configure wrong?
manual1_1_first_hibernate_apps.java
public static void main(String[] args) { args[0] ="list"; if (args.length <= 0) { System.err.println("argement was not given"); return; } manual1_1_first_hibernate_apps mgr = new manual1_1_first_hibernate_apps(); if (args[0].equals("store")) { mgr.createAndStoreEvent("My Event", new Date()); } else if (args[0].equals("list")) { mgr.<Event>listEvents().stream() .map(e -> "Event: " + e.getTitle() + " Time: " + e.getDate()) .forEach(System.out::println); } Util.getSessionFactory().close(); } private <T> List<T> listEvents() { Session session = Util.getSessionFactory().getCurrentSession(); session.beginTransaction(); List<T> events = Util.autoCast(session.createQuery("from Event").list()); session.getTransaction().commit(); return events; }
Util.java
private static final SessionFactory sessionFactory; /** * build a SessionFactory */ static { try { // Create the SessionFactory from hibernate.cfg.xml // hibernate version lower than 4.x are as follows // # it successful termination. but buildSessionFactory method is deprecated. // sessionFactory = new Configuration().configure().buildSessionFactory(); // version 4.3 and later // # it does not terminate. I manually terminated. Configuration configuration = new Configuration().configure(); StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } /** * @return built SessionFactory */ public static SessionFactory getSessionFactory() { return sessionFactory; }
The following console log snippets when program terminate and use buildSessionFactory method.
2 08, 2014 8:42:25 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop INFO: HHH000030: Cleaning up connection pool [jdbc:derby:D:Javajdk1.7.0_03(x86)dbbintestdb]
but if do not use deprecated buildSessionFactory method and terminated(program is running), the above two lines do not appear.
ENVIRONMENT:
Hibernate 4.3.1 DERBY JRE 1.8 IntelliJ IDEA 13
Advertisement
Answer
maybe, I solved this problem.
I saw the thread dump after Util.getSessionFactory().close() called, a thread named “pool-2-thread-1” state was TIMED_WAITING (parking).
The following snippets dump
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.0-b69 mixed mode): "DestroyJavaVM" #16 prio=5 os_prio=0 tid=0x00000000020b9000 nid=0x3684 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "pool-2-thread-1" #15 prio=5 os_prio=0 tid=0x000000001bc27000 nid=0x3f0 waiting on condition [0x000000001ce6f000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x0000000080be30a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:744) "derby.rawStoreDaemon" #14 daemon prio=5 os_prio=0 tid=0x000000001b059000 nid=0xa3c in Object.wait() [0x000000001ba1f000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000805f6190> (a org.apache.derby.impl.services.daemon.BasicDaemon) at org.apache.derby.impl.services.daemon.BasicDaemon.rest(Unknown Source) - locked <0x00000000805f6190> (a org.apache.derby.impl.services.daemon.BasicDaemon) at org.apache.derby.impl.services.daemon.BasicDaemon.run(Unknown Source) at java.lang.Thread.run(Thread.java:744) "Timer-0" #13 daemon prio=5 os_prio=0 tid=0x000000001b08e800 nid=0x2160 in Object.wait() [0x000000001b6af000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x0000000080608118> (a java.util.TaskQueue) at java.lang.Object.wait(Object.java:502) at java.util.TimerThread.mainLoop(Timer.java:526) - locked <0x0000000080608118> (a java.util.TaskQueue) at java.util.TimerThread.run(Timer.java:505)
I thought the cause is thread named “pool-2-thread-1” that created by buildSessionFactory method.
As a result of comparing the two buildSessionFactory method, I noticed that ServiceRegistry resources has not released.
Program successfully terminated by releasing it.
The following code, I adding.
Util.java
configuration.setSessionFactoryObserver( new SessionFactoryObserver() { @Override public void sessionFactoryCreated(SessionFactory factory) {} @Override public void sessionFactoryClosed(SessionFactory factory) { ((StandardServiceRegistryImpl) serviceRegistry).destroy(); } } );
thanks.