2017-01-25 46 views
0

最近,我将Spring集成到了我的Jboss应用程序中。我还将组合一个将使用某些Spring服务类的独立应用程序。这里是我的独立来源:Spring Standalone不认可@Transactional

@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注释似乎被忽略。我无法弄清楚为什么。

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

更新

这是我的配置文件:

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

} 
+0

您为Spring配置了哪个事务管理器? – dunni

+0

我添加了我的配置文件,看到上面 - 对不起,应该贴出来,开始。目前,我正在使用JpaTransactionManager。在我的jboss中,我正在使用jtaTransactionManager。 –

+0

当然它被忽略。你正在配置一个'EntityManagerFactory'并且没有使用它。基本上你的整个配置是无用的。除去'getEntityManager()'方法并将'@ PersistenceContext'放在'private EntityManager'字段中。你应该首先得到一个'EntityManager'。你的代码也是危险的,因为你只获得一次EntityManager而不是一个事务绑定的。 –

回答

1

交易工作正常,他们根本不在你的设置中工作。这是因为您正在重新创建一个事务性约束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); 
    } 
} 

这就是你应该需要的。

+0

正确,这里是原因。 'Transactional'只适用于* Container Managed EntityManager *,意思是Spring(或JavaEE)使用'@ PersistenceContext'注入的。如果你有一个* Application Managed EntityManager *,意思是通过调用'EntityManagerFactory.createEntityManager()'来创建它,那么你的代码负责管理事务,并调用'EntityManager.getTransaction()。begin()'和' EntityManager.getTransaction()。commit()' –

+0

感谢提示家伙。我上面发布了一些更新和后续问题。附注 - 克劳斯,我实际上已经能够在过去使用EntityManagerFactory.createEntityManager而无需明确地开始或提交事务。我只是使用注释。 –