交易和JPA / Persistence.xml

4

我在使用Hibernate JPA实现时遇到了事务问题(我正在遵循Camel Tracer示例)。

我正在使用Hibernate JPA实现:

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>4.3.5.Final</version>
</dependency>

如果我在META-INF文件夹中包含一个persistence.xml,一切都可以正常工作:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             version="1.0">
  <persistence-unit name="tracer" transaction-type="RESOURCE_LOCAL">
    <class>org.apache.camel.processor.interceptor.jpa.JpaTraceEventMessage</class>
    <properties>
      <property name="hibernate.dialect" value="..."/>
      <property name="hibernate.connection.driver_class" value="..."/>
      <property name="hibernate.connection.url" value="..."/>
      <property name="hibernate.hbm2ddl.auto" value="create"/>
      <property name="hibernate.connection.username" value="..." />
      <property name="hibernate.connection.password" value="..."/>
    </properties>
  </persistence-unit>
</persistence>

我希望使用Java的方式,因此我删除了persistence.xml文件并创建了以下的bean:
@Configuration
@EnableTransactionManagement
public class AppConfiguration
{
      @Bean public EntityManagerFactory entMngFac()
      {
        EntityManagerFactory emf  = Persistence.createEntityManagerFactory("tracer");
        return emf;
      }
      @Bean public DataSource ds()
      {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("...");
        dataSource.setUrl("...");
        dataSource.setUsername( "..." );
        dataSource.setPassword( "..." );
        return dataSource;
      }
      @Bean public PlatformTransactionManager ptm(EntityManagerFactory emf, DataSource ds)
      {
        JpaTransactionManager jpat = new JpaTransactionManager();
        jpat.setDataSource(ds);
        jpat.setEntityManagerFactory(emf);
        return jpat;
      }
      @Bean public TransactionTemplate tranTemp(PlatformTransactionManager ptm)
      {
        TransactionTemplate tt = new TransactionTemplate();
        tt.setTransactionManager(ptm);
        return tt;
      }
}

保存后,当Camel尝试刷新创建的JPATracer对象时,会出现以下异常:

javax.persistence.TransactionRequiredException: no transaction is in progress
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1171)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1332)
    at org.apache.camel.component.jpa.JpaProducer$1.doInTransaction(JpaProducer.java:86)

这有点奇怪,因为“未进行交易”错误来自“doInTransaction”方法。
我的想法是Camel正在启动事务,然后Hibernate尝试刷新对象,并且不知道Camel已经启动的事务? 所以在某个地方存在事务的混合,但我无法找出原因。
1个回答

3
尝试使用以下EntityManagerFactory配置(请注意packagesToScan的调用)
@Bean
public EntityManagerFactory entityManagerFactory() {
   LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
   em.setDataSource(ds());
   em.setPackagesToScan(new String[] { "org.apache.camel.processor.interceptor.jpa" });
   JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
   em.setJpaVendorAdapter(vendorAdapter);
   return em.getObject();
}

没错!就是这样。不指定要扫描的包会导致“TransactionRequiredException”异常。我得记住这个。再次感谢! - kwh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接