【发布时间】:2014-04-11 14:34:07
【问题描述】:
我有一个使用 spring 4.0、JPA 2.1、Hibernate 4.3.5、Glassfish 4.0 和 JTA 事务管理器的应用程序。
在我将 JPA 从 2.0 更新到 2.1 并从 Hibernate 4.2.x 更新到 4.3 之后,尽管日志看起来没问题,但数据不再保存到数据库中。
所以这些是可能的配置文件:
实体管理器
<bean id="emfCC" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="CCDS" />
<property name="packagesToScan" value="com.videanuadrian.core.entity" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.connection.autocommit">false </prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.SunONETransactionManagerLookup</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.ehcache.EhCacheProvider</prop>
<prop key="hibernate.generate_statistics">false</prop>
</props>
</property>
我的交易经理:
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="java:appserver/TransactionManager"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes >
<tx:method name="get*" rollback-for="java.lang.Exception" propagation="REQUIRED" read-only="true"/>
<tx:method name="is*" rollback-for="java.lang.Exception" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" rollback-for="java.lang.Exception" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
<aop:aspectj-autoproxy/>
<aop:config>
<aop:pointcut id="cs" expression="execution(* com.videanuadrian.contactcenter.services..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="cs" />
</aop:config>
<aop:config>
<aop:pointcut id="pcCore" expression="execution(* com.videanuadrian.core.impl.services..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pcCore"/>
</aop:config>
<jee:jndi-lookup id="CCDS" jndi-name="jdbc/contactCenter"/>
我所有的 DAO 类都继承了这个类:
public abstract class GenericDAOImpl<T> implements GenericDAO<T> {
@PersistenceContext(type = PersistenceContextType.TRANSACTION,synchronization=SynchronizationType.SYNCHRONIZED)
protected EntityManager em;
private Class<T> type;
protected static final Logger logger = Logger.getLogger(GenericDAOImpl.class);
public GenericDAOImpl() {
Type t = getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType) t;
type = (Class) pt.getActualTypeArguments()[0];
}
public EntityManager getEm() {
return em;
}
public void setEm(EntityManager em) {
this.em = em;
}
@Override
public T create(final T t) {
this.em.persist(t);
return t;
}
@Override
public void delete(final Object id) {
this.em.remove(this.em.getReference(type, id));
}
@Override
public T find(final Object id) {
return (T) this.em.find(type, id);
}
@Override
public T update(final T t) {
return this.em.merge(t);
}
@Override
public void flush(){
this.em.flush();
}
}
这是我的服务类:
@Named
public class ApplicationServiceImpl implements ApplicationService {
@Inject
private ApplicationDAO applicationDAO;
@Override
public Long updateApplication(Application app) {
if (app == null)
return null;
applicationDAO.update(app);
return app.getId();
}
}
在我点击 updateApplication 方法后,日志是正确的,一切似乎都正常,但更新没有持久化到数据库。起初这似乎事务没有或事务没有创建,但这里是日志:
AbstractPlatformTransactionManager.java:367) - Creating new transaction with name [com.videanuadrian.core.impl.services.ApplicationServiceImpl.updateApplication]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT,-java.lang.Exception
(TransactionSynchronizationManager.java:272) - Initializing transaction synchronization
(TransactionAspectSupport.java:447) - Getting transaction for [com.videanuadrian.core.impl.services.ApplicationServiceImpl.updateApplication]
(EntityManagerFactoryUtils.java:272) - Opening JPA EntityManager
(EntityManagerFactoryUtils.java:290) - Registering transaction synchronization for JPA EntityManager
(TransactionSynchronizationManager.java:193) - Bound value [org.springframework.orm.jpa.EntityManagerHolder@48ff5d9c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@e9c2514] to thread [http-listener-1(3)]
(AbstractBeanFactory.java:249) - Returning cached instance of singleton bean 'auditLogAspectImpl'
(AbstractPlatformTransactionManager.java:472) - Participating in existing transaction
(TransactionAspectSupport.java:447) - Getting transaction for [com.videanuadrian.core.impl.services.UserServiceImpl.getUser]
(TransactionSynchronizationManager.java:140) - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@48ff5d9c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@e9c2514] bound to thread [http-listener-1(3)]
(TransactionSynchronizationManager.java:140) - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@48ff5d9c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@e9c2514] bound to thread [http-listener-1(3)]
(TransactionAspectSupport.java:476) - Completing transaction for [com.videanuadrian.core.impl.services.UserServiceImpl.getUser]
(AbstractPlatformTransactionManager.java:472) - Participating in existing transaction
(TransactionAspectSupport.java:447) - Getting transaction for [com.videanuadrian.core.impl.services.AuditLogServiceImpl.addAuditLogEvent]
(TransactionSynchronizationManager.java:140) - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@48ff5d9c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@e9c2514] bound to thread [http-listener-1(3)]
(TransactionSynchronizationManager.java:140) - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@48ff5d9c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@e9c2514] bound to thread [http-listener-1(3)]
(TransactionSynchronizationManager.java:140) - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@48ff5d9c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@e9c2514] bound to thread [http-listener-1(3)]
(TransactionSynchronizationManager.java:140) - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@48ff5d9c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@e9c2514] bound to thread [http-listener-1(3)]
(TransactionAspectSupport.java:476) - Completing transaction for [com.videanuadrian.core.impl.services.AuditLogServiceImpl.addAuditLogEvent]
(TransactionAspectSupport.java:476) - Completing transaction for [com.videanuadrian.core.impl.services.ApplicationServiceImpl.updateApplication]
(AbstractPlatformTransactionManager.java:926) - Triggering beforeCommit synchronization
(AbstractPlatformTransactionManager.java:939) - Triggering beforeCompletion synchronization
(TransactionSynchronizationManager.java:243) - Removed value [org.springframework.orm.jpa.EntityManagerHolder@48ff5d9c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@e9c2514] from thread [http-listener-1(3)]
(EntityManagerFactoryUtils.java:435) - Closing JPA EntityManager
(AbstractPlatformTransactionManager.java:755) - Initiating transaction commit
(AbstractPlatformTransactionManager.java:952) - Triggering afterCommit synchronization
(AbstractPlatformTransactionManager.java:968) - Triggering afterCompletion synchronization
(TransactionSynchronizationManager.java:331) - Clearing transaction synchronization
(RequestLoggingPhaseListener.java:42) - Entering JSF Phase: RESTORE_VIEW 1
(RequestLoggingPhaseListener.java:42) - Entering JSF Phase: RENDER_RESPONSE 6
如果我启用 sql_log,我将看不到正在执行的更新语句....
我怀疑 JPA 2.1 之间的任何东西我的 entityManager、事务管理器,但我不知道它是什么...
有什么想法吗?
【问题讨论】:
-
您好 Andei,我已经尝试过了,唯一的例外是没有正在进行的交易。此外,如果我将 MANDATORY 置于 updateApplication() 的传播级别,我会得到相同的异常。但只要我在日志中有这一行:AbstractPlatformTransactionManager.java:367) - 创建名称为 [com.videanuadrian. core.impl.services.ApplicationServiceImpl.updateApplication]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT,-java.lang.Exception
-
我没有 persitence.xml 文件,因为我读到如果您将 packagesToScan 放入并将所有属性从 persitence.xml 移动到 entityManager Bean,您可以在没有它的情况下“生存”。我不得不说,当我使用 jpa2.0 和 hibernate 4.2 时,我有 persitence.xml 文件。
-
我没有尝试使用@Transactional,因为事务分界是通过AOP 实现的。因此,对于包中的每个方法:
应该打开一个事务。而且,奇怪的是,在日志中似乎事务是打开的,但是...... -
为了让@Transactional 工作,我认为我的xml 文件中必须有
。 -
我只能说明问题是什么,不知道怎么解决(没有spring经验):entitymanager没有自动加入JTA事务。
标签: java spring hibernate jpa jta