2017-01-25 50 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而無需明確地開始或提交事務。我只是使用註釋。 –