Spring Standalone无法识别@Transactional

时间:2017-01-25 16:40:23

标签: java spring persistence

最近,我将Spring集成到了我的Jboss应用程序中。我还整理了一个独立的应用程序,它将使用一些Spring服务类。这是我的独立来源:

@Component
public class StandaloneTest {

public static ApplicationContext context;

public static void main(String[] args) {
    context = new AnnotationConfigApplicationContext(StandaloneSpringBeanConfiguration.class);
    StandaloneTest test = context.getBean(StandaloneTest.class);
    System.out.println(context);
    test.startProcess();
}

public StandaloneTest() {

}

/**
 * Start the main process
 */
private void startProcess() {
        run();
}

private void run() {
    TestService testService = context.getBean(TestService.class);
    testService.transactionalTest();
    System.out.println("finished");
}

以下是TestService的来源:

@Service
public class TestServiceImpl implements TestService {

public GeneralDAO generalDAO;

private EntityManager em;

private EntityManagerFactory emf;

public TestServiceImpl(){}

    @Transactional
public void transactionalTest() {
    Something something = new Something();
    getEntityManager().persist(something);
} 

    public EntityManager getEntityManager() {
    if (em == null) {
        emf = Persistence.createEntityManagerFactory("xxx");
        em = emf.createEntityManager();
    }
    return em;
} 


}

当我在Jboss服务器中运行此方法时,@ Transactal注释按预期工作。但是,当我运行独立应用程序时,似乎忽略了@Transactional注释。我无法弄清楚原因。

如果有人知道我需要做些什么才能使其发挥作用或有任何想法/意见,请分享。谢谢!

更新

这是我的配置文件:

@Configuration
@ComponentScan
@EnableTransactionManagement
public class StandaloneSpringBeanConfiguration {

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setPersistenceUnitName("myPersistenceContext");
      em.setDataSource(dataSource());
      em.setPackagesToScan(new String[] { "xxx.xxx.xxx"});

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
   //   em.setJpaProperties(additionalProperties());

      return em;
   }

   @Bean
   public DataSource dataSource(){
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      dataSource.setDriverClassName("com.mysql.jdbc.Driver");
      dataSource.setUrl("jdbc:mysql://localhost:3306/jboss_test");
      dataSource.setUsername( "root" );
      dataSource.setPassword( "root" );
      return dataSource;
   }

   @Bean
   public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
          JpaTransactionManager transactionManager = new JpaTransactionManager(emf);
          transactionManager.setEntityManagerFactory(emf);
          return transactionManager;
    }


   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
      return new PersistenceExceptionTranslationPostProcessor();
   }

更新更新

@Service
public class TestServiceImpl implements TestService {

public GeneralDAO generalDAO;

@PersistenceContext
private EntityManager em;

private EntityManagerFactory emf;

public TestServiceImpl(){}

@Transactional
public void transactionalTest() {
Something something = new Something();
em.persist(something);
} 

}

这绝对让我朝着正确的方向前进。我现在收到此错误:没有可用的JTA UserTransaction - 指定' userTransaction'或者' userTransactionName'或者' transactionManager'或者' transactionManagerName'

我无法弄清楚原因,但问题是我选择的transactionManager?我正在阅读某个地方我需要使用JOTM或Atomikos独立,但我不认为JOTM可以在Spring 4中使用,而Atomikos要求我使用Maven,这对我来说不是一个选择。使用JTATransactionManager给了我相同的结果。

工作解决方案

JTA错误似乎在今天早上解决了。不确定发生了什么。然后,我必须确保LocalContainerEntityManagerFactoryBean正在扫描所有必需的包,因为我收到了IllegalArgumentException未知实体

配置

public class StandaloneSpringBeanConfiguration {

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource());
      em.setPackagesToScan(new String[] { "xxx.xxx.xxx", "xxx.xxx.xxx"});

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
   //   em.setJpaProperties(additionalProperties());

      return em;
   }

   @Bean
   public DataSource dataSource(){
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      dataSource.setDriverClassName("com.mysql.jdbc.Driver");
      dataSource.setUrl("jdbc:mysql://localhost:3306/jboss_test");
      dataSource.setUsername( "root" );
      dataSource.setPassword( "root" );
      return dataSource;
   }

   @Bean
   public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
       JpaTransactionManager transactionManager = new JpaTransactionManager();
       transactionManager.setEntityManagerFactory(emf);
       return transactionManager;
    } 


   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
      return new PersistenceExceptionTranslationPostProcessor();
   }

服务类

@Service
public class TestServiceImpl implements TestService {

public GeneralDAO generalDAO;

@PersistenceContext
private EntityManager em;

private EntityManagerFactory emf;

public TestServiceImpl(){}

@Transactional
public void transactionalTest() {
Something something = new Something();
em.persist(something);
} 

}

1 个答案:

答案 0 :(得分:1)

交易工作正常,他们根本无法在您的设置中工作。这是因为您正在重新创建事务绑定EntityManager

基本上,TestServiceImpl的代码存在缺陷。您应该删除getEntityManager()方法,而是使用EntityManager注释@PersistenceContext字段。

@Service
public class TestServiceImpl implements TestService {

  public GeneralDAO generalDAO;

  @PersistenceContext
  private EntityManager em;

  public TestServiceImpl(){}

    @Transactional
    public void transactionalTest() {
      Something something = new Something();
      em.persist(something);
    } 
}

这就是你应该需要的一切。