2012-04-22 3 views
13

Mam prostą klasę, która rozpoczyna 3 wątki i zapisuje nowy obiekt w każdym wątku. Ale dostaję wyjątek, którego nie mogę zrozumieć. Czy ktoś może mi pomóc zrozumieć, dlaczego wyjątek?Hibernate UnknownServiceException: Nieznana usługa żądana jako zakończona transakcja

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()); 

    } 
} 

I to jest odpowiednia część pliku dziennika pokazujący wyjątek:

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> 

+0

Z której wersji Hibernacji korzystałeś? Czy mógłbyś opublikować plik konfiguracyjny Hibernate? – kyiu

+0

Używam hibernacji 4.1. Zmodyfikowałem mój post, dołączając plik hibernate.cfg.xml. Dzięki. – sachinrahulsourav

+0

Zmień tę właściwość 1 Zobacz poniżej link http://stackoverflow.com/questions/9802684/hibernate-config-connection-pool- size –

Odpowiedz

17

obiekt Session w Hibernate nie jest wątku bezpieczne, nie należy używać tej samej sesji w różnych wątków, chyba że synchornize dostęp do obiektu Session.

3

Zadzwoń pod .openSession() zamiast .getCurrentSession() po getSessionFactory(). Obiekt
jest bezpieczny dla wątków, ale każdy obiekt Session powinien być jednowątkowy.

3

Sesja jest w rzeczywistości Unit of Work, która powinna być związana z bieżącym wątkiem wykonawczym. Jednostka pracy grupuje wiele operacji DML w ramach jednej transakcji, która może się powieść tylko wtedy, gdy wszystkie operacje zakończą się pomyślnie. Tak więc sesja jest atomowa, a atomowość oznacza pojedynczy wątek operacyjny.

Sesja jest także 1-sza pamięci podręcznej poziomu, więc w bieżącej sesji zawsze otrzymasz odwołanie do tego samego obiektu, niezależnie od tego, ile razy wywołasz session.get() lub session.load(). Jeśli sesja była bezpieczna dla wątków niż w czasie spłukiwania, możesz wykonać inne zmiany pośrednika transakcji. Sesja musi więc być odizolowana od innych sesji wykonawczych, a izolacja oznacza pojedynczy wątek operacyjny.

Sesja nie ma więc nic wspólnego z bezpieczeństwem, aby zachować wymagania dotyczące atomowości i izolacji.

+0

Hej Vlad, znowu szukam twojej pomocy, ponieważ widzę, że odpowiedziałeś na pytanie z prawdopodobnie podobnym problemem. Czy możesz rzucić okiem na to:/http://stackoverflow.com/questions/31694247/unknownserviceexception-unknown-service-requested-hibernate-spring? – displayname

0

jeśli jest to pomocne dla kogokolwiek innego, dla mnie oznaczało to, że "zrobiłeś szpiega z mockito (baza danych)" w poprzednim badaniu jednostkowym, które w jakiś sposób spowodowało hibernację. Domyśl.