Java Spring@Transactional方法中没有事务启动
在使用Spring(3.0.5)、Hibernate(3.6.0)和Wicket(1.4.14)开发应用程序时,我遇到了一个奇怪的问题。问题是:我无法将任何对象保存或修改到数据库中。“cannot”是指对象中的所有更改或对EntityManager.persist(foo)的调用都被简单地、默默地忽略。选择工作 示例案例很简单——在某个wicket页面上,我尝试将对象保存到数据库中,如下所示Java Spring@Transactional方法中没有事务启动,java,hibernate,spring,jpa,transactional,Java,Hibernate,Spring,Jpa,Transactional,在使用Spring(3.0.5)、Hibernate(3.6.0)和Wicket(1.4.14)开发应用程序时,我遇到了一个奇怪的问题。问题是:我无法将任何对象保存或修改到数据库中。“cannot”是指对象中的所有更改或对EntityManager.persist(foo)的调用都被简单地、默默地忽略。选择工作 示例案例很简单——在某个wicket页面上,我尝试将对象保存到数据库中,如下所示 public class ComicDetailsPage extends PublicBasePage
public class ComicDetailsPage extends PublicBasePage {
@Override
protected void onConfigure() {
System.out.println("In onConfigure");
super.onConfigure();
comicDAO.insert("abc");
}
@SpringBean(name="comicDAO")
private ComicDAO comicDAO;
(....)
这是comicDAO
@Service
public class ComicDAO {
@PersistenceContext
private EntityManager em;
(...)
@Transactional
public void insert(String title) {
Comic c = new Comic();
c.setTitle(title);
em.persist(c);
}
@Transactional
public Comic add1toTitle(int pk) {
System.out.println("Beginning fetching");
Comic c = em.find(Comic.class, pk);
System.out.println("Fetched updating");
c.setTitle(c.getTitle()+"1");
System.out.println("Updated persisting");
em.persist(c);
System.out.println("Persisted returning");
return c;
}
我打开了日志记录,下面是日志的相关部分(Hibernate和Spring都设置为跟踪)。我在我认为重要的行中添加了**
In onConfigure
01:53:19.330 [qtp2119047503-15] DEBUG o.s.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'txManager'
**01:53:19.330 [qtp2119047503-15] DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 13006687993**
**01:53:19.330 [qtp2119047503-15] DEBUG org.hibernate.transaction.JDBCTransaction - begin**
01:53:19.330 [qtp2119047503-15] DEBUG org.hibernate.jdbc.ConnectionManager - opening JDBC connection
01:53:19.335 [qtp2119047503-15] DEBUG org.hibernate.transaction.JDBCTransaction - current autocommit status: true
01:53:19.335 [qtp2119047503-15] DEBUG org.hibernate.transaction.JDBCTransaction - disabling autocommit
01:53:19.336 [qtp2119047503-15] TRACE org.hibernate.jdbc.JDBCContext - after transaction begin
01:53:19.336 [qtp2119047503-15] DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 13006687993
01:53:19.336 [qtp2119047503-15] TRACE org.hibernate.impl.SessionImpl - setting flush mode to: AUTO
01:53:19.336 [qtp2119047503-15] TRACE org.hibernate.impl.SessionImpl - setting cache mode to: NORMAL
01:53:19.337 [qtp2119047503-15] TRACE org.hibernate.engine.IdentifierValue - id unsaved-value: 0
01:53:19.337 [qtp2119047503-15] TRACE org.hibernate.event.def.AbstractSaveEventListener - transient instance of: pl.m4ks.comics.entity.Comic
01:53:19.337 [qtp2119047503-15] TRACE org.hibernate.event.def.DefaultPersistEventListener - saving transient instance
**01:53:19.338 [qtp2119047503-15] TRACE org.hibernate.event.def.AbstractSaveEventListener - saving [pl.m4ks.comics.entity.Comic#<null>]**
**01:53:19.341 [qtp2119047503-15] DEBUG org.hibernate.event.def.AbstractSaveEventListener - delaying identity-insert due to no transaction in progress**
01:53:19.341 [qtp2119047503-15] TRACE org.hibernate.impl.SessionImpl - closing session
01:53:19.341 [qtp2119047503-15] TRACE org.hibernate.jdbc.ConnectionManager - connection already null in cleanup : no action
01:53:19.341 [qtp2119047503-15] DEBUG org.hibernate.transaction.JDBCTransaction - commit
**01:53:19.341 [qtp2119047503-15] TRACE org.hibernate.impl.SessionImpl - automatically flushing session**
01:53:19.341 [qtp2119047503-15] TRACE org.hibernate.jdbc.JDBCContext - before transaction completion
01:53:19.341 [qtp2119047503-15] TRACE org.hibernate.impl.SessionImpl - before transaction completion
01:53:19.342 [qtp2119047503-15] DEBUG org.hibernate.transaction.JDBCTransaction - re-enabling autocommit
01:53:19.342 [qtp2119047503-15] DEBUG org.hibernate.transaction.JDBCTransaction - committed JDBC Connection
01:53:19.342 [qtp2119047503-15] TRACE org.hibernate.jdbc.JDBCContext - after transaction completion
01:53:19.342 [qtp2119047503-15] DEBUG org.hibernate.jdbc.ConnectionManager - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
01:53:19.342 [qtp2119047503-15] TRACE org.hibernate.impl.SessionImpl - after transaction completion
01:53:19.342 [qtp2119047503-15] TRACE org.hibernate.impl.SessionImpl - closing session
01:53:19.342 [qtp2119047503-15] TRACE org.hibernate.jdbc.ConnectionManager - performing cleanup
01:53:19.342 [qtp2119047503-15] DEBUG org.hibernate.jdbc.ConnectionManager - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
01:53:19.342 [qtp2119047503-15] TRACE org.hibernate.jdbc.JDBCContext - after transaction completion
01:53:19.342 [qtp2119047503-15] DEBUG org.hibernate.jdbc.ConnectionManager - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
01:53:19.342 [qtp2119047503-15] TRACE org.hibernate.impl.SessionImpl - after transaction completion
onconfig中的
01:53:19.330[qtp2119047503-15]调试o.s.beans.factory.support.DefaultListableBeanFactory-返回singleton bean'txManager'的缓存实例
**01:53:19.330[qtp2119047503-15]调试org.hibernate.impl.SessionImpl-时间戳为13006687993的已打开会话**
**01:53:19.330[qtp2119047503-15]调试org.hibernate.transaction.JDBCTransaction-开始**
01:53:19.330[qtp2119047503-15]调试org.hibernate.jdbc.ConnectionManager-打开jdbc连接
01:53:19.335[qtp2119047503-15]调试org.hibernate.transaction.JDBCTransaction-当前自动提交状态:true
01:53:19.335[qtp2119047503-15]调试org.hibernate.transaction.JDBCTransaction-禁用自动提交
01:53:19.336[qtp2119047503-15]跟踪org.hibernate.jdbc.jdbcontext-事务开始后
01:53:19.336[qtp2119047503-15]调试org.hibernate.impl.SessionImpl-时间戳为13006687993的已打开会话
01:53:19.336[qtp2119047503-15]TRACE org.hibernate.impl.SessionImpl-将刷新模式设置为:自动
01:53:19.336[qtp2119047503-15]TRACE org.hibernate.impl.SessionImpl-将缓存模式设置为:正常
01:53:19.337[qtp2119047503-15]TRACE org.hibernate.engine.IdentifierValue-id未保存值:0
01:53:19.337[qtp2119047503-15]TRACE org.hibernate.event.def.AbstractSaveEventListener-的瞬态实例:pl.m4ks.comics.entity.Comic
01:53:19.337[qtp2119047503-15]TRACE org.hibernate.event.def.DefaultPersistEventListener-保存临时实例
**01:53:19.338[qtp2119047503-15]TRACE org.hibernate.event.def.AbstractSaveEventListener-保存[pl.m4ks.comics.entity.Comic]**
**01:53:19.341[qtp2119047503-15]调试org.hibernate.event.def.AbstractSaveEventListener-由于没有正在进行的事务,正在延迟标识插入**
01:53:19.341[qtp2119047503-15]TRACE org.hibernate.impl.SessionImpl-结束会话
01:53:19.341[qtp2119047503-15]TRACE org.hibernate.jdbc.ConnectionManager-清除中的连接已为空:无操作
01:53:19.341[qtp2119047503-15]调试org.hibernate.transaction.JDBCTransaction-commit
**01:53:19.341[qtp2119047503-15]TRACE org.hibernate.impl.SessionImpl-自动刷新会话**
01:53:19.341[qtp2119047503-15]跟踪org.hibernate.jdbc.jdbcontext-事务完成前
01:53:19.341[qtp2119047503-15]TRACE org.hibernate.impl.SessionImpl-事务完成前
01:53:19.342[qtp2119047503-15]调试org.hibernate.transaction.JDBCTransaction-重新启用自动提交
01:53:19.342[qtp2119047503-15]调试org.hibernate.transaction.jdbctransation-提交的JDBC连接
01:53:19.342[qtp2119047503-15]跟踪org.hibernate.jdbc.jdbcontext-事务完成后
01:53:19.342[qtp2119047503-15]DEBUG org.hibernate.jdbc.ConnectionManager-在会话上以on_close连接释放模式完成事务;确保关闭会话以释放JDBC资源!
01:53:19.342[qtp2119047503-15]TRACE org.hibernate.impl.SessionImpl-事务完成后
01:53:19.342[qtp2119047503-15]TRACE org.hibernate.impl.SessionImpl-结束会话
01:53:19.342[qtp2119047503-15]TRACE org.hibernate.jdbc.ConnectionManager-正在执行清理
01:53:19.342[qtp2119047503-15]调试org.hibernate.jdbc.ConnectionManager-发布jdbc连接[(打开准备语句:0,全局:0)(打开结果集:0,全局:0)]
01:53:19.342[qtp2119047503-15]跟踪org.hibernate.jdbc.jdbcontext-事务完成后
01:53:19.342[qtp2119047503-15]DEBUG org.hibernate.jdbc.ConnectionManager-在会话上以on_close连接释放模式完成事务;确保关闭会话以释放JDBC资源!
01:53:19.342[qtp2119047503-15]TRACE org.hibernate.impl.SessionImpl-事务完成后
当然,没有对象被保存到数据库中
最后一个文件-my applicationCOntext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans (...)>
<context:component-scan base-package="pl.m4ks.comics"/>
<context:annotation-config />
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:8889/comics" />
<property name="username" value="root"/>
<property name="password" value="root" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="main" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="packagesToScan">
<value>pl.m4ks.comics</value>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
</beans>
pl.m4ks.comics
我不知道会出现什么问题,也不知道如何解决。我不想在代码中管理事务——这就是Spring的用途 您需要在EntityManager上调用以下方法 要在数据库中进行实际保存,您需要定义Hibernate
SessionFactory
和JPAEntitymanagerFactory
。会是哪一个?可以使用Hibernate的会话API或JPA的Entitymanager API,并将Hibernate作为提供程序,但不能同时使用两者
b) 您已经定义了一个HibernateTransactionManager
,但由于您在代码中使用的是EntityManager
,因此需要一个JpaTransactionManager
:
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf"/>
</bean
您是否尝试过在hibernate配置中设置hibernate.connection.autocommit=true?这将解决问题。但是,您必须弄清楚这种方法的效率。wicket类(system out the.getClass())中dao的实际类型是什么。DAO有哪些构造函数?删除了wicket标记,因为它与这个问题无关(您的问题不在wicket代码中)。添加了不正确的Java和JPA标记。如果Spring TransactionManager设置正确,entityManager.flush()将被自动调用
<?xml version="1.0" encoding="UTF-8"?>
<beans (...)>
<context:component-scan base-package="pl.m4ks.comics"/>
<context:annotation-config />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:8889/comics" />
<property name="username" value="root"/>
<property name="password" value="root" />
</bean>
<!-- use either this: -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="main" />
<property name="dataSource" ref="dataSource" />
</bean>
<!-- or this -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="packagesToScan">
<value>pl.m4ks.comics</value>
</property>
</bean>
<!-- (but not both) -->
<!-- this is correct for AnnotationSessionFactoryBean, but not if you use
LocalContainerEntityManagerFactoryBean -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- not necessary, <context:annotation-config /> automatically includes this -->
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
</beans>