Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate UnknownServiceException :Unknown service requested as transaction completed

I have a simple class which starts 3 threads and saves a new object in each thread. But I am getting exception which i cannot understand. Can anyone help me understand why the exception?

package test;

import java.util.Date;

import org.hibernate.Session;

import domain.Event;

import util.HibernateUtil;

public class EventBeanTest {

    public static void main(String [] args) {

        Event e1 = new Event();
        e1.setTitle("111");
        e1.setDate(new Date());

        Event e2 = new Event();
        e2.setTitle("222");
        e2.setDate(new Date());

        Event e3 = new Event();
        e3.setTitle("333");
        e3.setDate(new Date());


        Thread t1 = new Thread(new EventRunnable(e1));
        Thread t2 = new Thread(new EventRunnable(e2));
        Thread t3 = new Thread(new EventRunnable(e3));

        t1.setName("event - 111");
        t2.setName("event - 222");
        t3.setName("event - 333");

        t1.start();
        t2.start();
        t3.start();

    }

}

class EventRunnable implements Runnable {
    private Event event;

    public EventRunnable(Event event) {
        this.event = event;
    }

    public void run() {

        System.out.println("Starting thread : " + Thread.currentThread().getName());

        Session session = HibernateUtil.getSessionFactory().getCurrentSession();

        session.beginTransaction();

        session.saveOrUpdate(event);
        session.getTransaction().commit();

        HibernateUtil.getSessionFactory().close();

        System.out.println("Finishing thread : " + Thread.currentThread().getName());

    }
}

And this is the relevant part of the log file showing the exception:

Hibernate: select max(EVENT_ID) from test.EVENTS
Hibernate: insert into test.EVENTS (EVENT_DATE, TITLE, EVENT_ID) values (?, ?, ?)
Hibernate: insert into test.EVENTS (EVENT_DATE, TITLE, EVENT_ID) values (?, ?, ?)
Hibernate: insert into test.EVENTS (EVENT_DATE, TITLE, EVENT_ID) values (?, ?, ?)
Apr 22, 2012 2:46:55 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost:3306/test]
Finishing thread : event - 333
Apr 22, 2012 2:46:55 PM org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction afterAfterCompletion
INFO: HHH000425: Could not close session; swallowing exception[org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.stat.spi.StatisticsImplementor]] as transaction completed
Exception in thread "event - 222" org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.stat.spi.StatisticsImplementor]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:126)
    at org.hibernate.internal.SessionFactoryImpl.getStatisticsImplementor(SessionFactoryImpl.java:1708)
    at org.hibernate.internal.SessionFactoryImpl.getStatistics(SessionFactoryImpl.java:1704)
    at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.afterTransaction(TransactionCoordinatorImpl.java:140)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.afterTransactionCompletion(JdbcTransaction.java:138)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:184)
    at test.EventRunnable.run(EventBeanTest.java:60)
    at java.lang.Thread.run(Thread.java:722)
Apr 22, 2012 2:46:55 PM org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction afterAfterCompletion
INFO: HHH000425: Could not close session; swallowing exception[org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.stat.spi.StatisticsImplementor]] as transaction completed
Exception in thread "event - 111" org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.stat.spi.StatisticsImplementor]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:126)
    at org.hibernate.internal.SessionFactoryImpl.getStatisticsImplementor(SessionFactoryImpl.java:1708)
    at org.hibernate.internal.SessionFactoryImpl.getStatistics(SessionFactoryImpl.java:1704)
    at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.afterTransaction(TransactionCoordinatorImpl.java:140)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.afterTransactionCompletion(JdbcTransaction.java:138)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:184)
    at test.EventRunnable.run(EventBeanTest.java:60)
    at java.lang.Thread.run(Thread.java:722)

EDIT 1

<?xml version='1.0' encoding='utf-8'?>

<session-factory>

    <!-- Database connection settings -->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
    <property name="connection.username">vishnu</property>
    <property name="connection.password">con02305</property>

    <!-- JDBC connection pool (use the built-in) -->
    <property name="connection.pool_size">1</property>

    <!-- SQL dialect -->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>

    <!-- Disable the second-level cache  -->
    <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">true</property>

    <!-- Drop and re-create the database schema on startup 
    <property name="hbm2ddl.auto">update</property> -->

    <property name="default_schema">test</property>
    <property name="show_sql">true</property>

    <mapping resource="domain/Event.hbm.xml"/>

</session-factory>

like image 347
sachinrahulsourav Avatar asked Apr 22 '12 09:04

sachinrahulsourav


3 Answers

Session object in Hibernate is not thread safe, you should not use the same session in different threads, unless you synchornize access to Session object.

like image 50
Piotr Kochański Avatar answered Oct 30 '22 02:10

Piotr Kochański


Call .openSession() instead of .getCurrentSession() after getSessionFactory().
The sessionFactory object is thread-safe but each Session object should be single-threaded.

like image 31
kyiu Avatar answered Oct 30 '22 01:10

kyiu


A Session is actually a Unit of Work which should be bound to the current executing Thread. A unit of work group multiple DML operations inside a single transaction which can succeed only if all operations succeed. So a session is atomic, and atomicity implies a single operating thread.

The Session is also the 1st Level Cache, so in the current Session you will always get the same Entity object reference, no matter how many times you call session.get() or session.load(). If a Session were thread-safe than during flush time you might execute other transaction intermediary changes. So a Session must be isolated from other executing Session, and isolation implies a single operating thread.

So, a Session is not meant to be thread-safe to preserve the atomicity and isolation requirements.

like image 32
Vlad Mihalcea Avatar answered Oct 30 '22 00:10

Vlad Mihalcea