Spring 独立无法识别@Transactional

Spring Standalone not recognizing @Transactional

最近,我将 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 服务器中使用此方法时,@Transactional 注释按预期工作。但是,当我 运行 独立应用程序时,@Transactional 注释似乎被忽略了。我不知道为什么。

如果有人知道我需要做什么才能让它工作或有任何 ideas/comments,请分享。谢谢!

更新

这是我的配置文件:

@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 Unknown Entity

配置

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();
   }

服务Class

@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);
} 

}

交易工作正常,只是它们在您的设置中不起作用。这是因为您正在重新创建交易绑定 EntityManager

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

@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);
    } 
}

这就是您所需要的。