Вопрос по transactions, hibernate, java, jpa, orm – Hibernate UnknownServiceException: неизвестный сервис запрошен как транзакция завершена

13

У меня есть простой класс, который запускает 3 потока и сохраняет новый объект в каждом потоке. Но я получаю исключение, которое не могу понять. Может кто-нибудь помочь мне понять, почему исключение?

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

    }
}
</code>

И это соответствующая часть файла журнала, показывающая исключение:

<code>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)
</code>

EDIT 1

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

<code><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>
</code>

Измените это свойство & lt; имя свойства = "connection.pool_size" & gt; 1 & lt; / property & gt; См ссылку нижеstackoverflow.com/questions/9802684/… Amit Jain
У меня была похожая проблема, которая была вызвана некоторыми попытками, которые были предприняты послеSessionFactory закрытие объекта. ROMANIA_engineer
Я использую Hibernate 4.1. Я отредактировал свой пост, включив в него файл hibernate.cfg.xml. Благодарю. sachinrahulsourav
Какую версию Hibernate вы использовали? Не могли бы вы опубликовать файл конфигурации Hibernate? kyiu

Ваш Ответ

4   ответа
3

.openSession() вместо.getCurrentSession() послеgetSessionFactory().
sessionFactory объект является потокобезопасным, но каждыйSession объект должен быть однопоточным.

3

Единица работы который должен быть привязан к текущему исполняющему потоку. Единица работы группирует несколько операций DML внутри одной транзакции, которая может быть успешной, только если все операции выполнены успешно. Таким образом, сеанс является атомарным, а атомарность подразумевает один рабочий поток.

Сеанс также является кэшем 1-го уровня, поэтому в текущем сеансе вы всегда получите одну и ту же ссылку на объект Entity, независимо от того, сколько раз вы вызываете session.get () или session.load (). Если сеанс был поточно-ориентированным, чем во время сброса, вы могли бы выполнить другие промежуточные изменения транзакции. Таким образом, Сеанс должен быть изолирован от другого выполняющегося Сеанса, а изоляция подразумевает один работающий поток.

Таким образом, Session не предназначен для обеспечения многопоточности для сохранения требований атомарности и изоляции.

Привет, Влад, я снова обращаюсь к тебе за помощью, поскольку вижу, что ты ответил на вопрос с, возможно, похожей проблемой. Не могли бы вы взглянуть на это: /stackoverflow.com/questions/31694247/… ?
17

вы не должны использовать один и тот же сеанс в разных потоках, если только вы не синхронизируете доступ к объекту сеанса.

0

для меня это означало «вы сделали шпион (база данных)»; в предыдущем модульном тесте, в котором как-то прятался спящий режим. Пойди разберись.

Похожие вопросы