我有一个简单的类,它启动3个线程并在每个线程中保存一个新对象。但我得到了一些我无法理解的异常。任何人都可以帮助我理解为什么例外吗?
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());
}
}
这是显示异常的日志文件的相关部分:
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)
编辑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 :(得分:17)
Hibernate中的Session对象不是线程安全的,除非您同步访问Session对象,否则不应在不同的线程中使用相同的会话。
答案 1 :(得分:3)
在.openSession()
之后致电.getCurrentSession()
而不是getSessionFactory()
。
sessionFactory
对象是线程安全的,但每个Session
对象应该是单线程的。
答案 2 :(得分:3)
会话实际上是一个Unit of Work,它应绑定到当前正在执行的Thread。单个事务中的多个DML操作的工作组,只有在所有操作都成功时才能成功。因此会话是原子的,而原子性意味着一个操作线程。
Session也是第一级缓存,因此在当前Session中,无论您调用session.get()或session.load()多少次,您都将获得相同的Entity对象引用。如果会话是线程安全的而不是刷新时间,则可以执行其他事务中介更改。因此,Session必须与其他正在执行的Session隔离,而隔离意味着单个操作线程。
因此,会话并不意味着保持原子性和隔离要求的线程安全。
答案 3 :(得分:0)
如果它对其他人有帮助,对我来说,这意味着“你在之前的单元测试中做了一个模拟间谍(数据库)”,它以某种方式进行了休眠。去图。