2017-01-25 24 views
0

最近、JbossアプリケーションにSpringを統合しました。また、Springサービスクラスのいくつかを使用するスタンドアロンアプリケーションを作成しています。ここに私のスタンドアロンのソースは次のとおりです。ここでSpringスタンドアロンが@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のソースです:私は私のJBossサーバでこのメソッドを実行すると

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


} 

、@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 available - 'userTransaction'または 'userTransactionName'または 'transactionManager'または 'transactionManagerName'のいずれかを指定します。

原因を特定するのに問題がありますが、問題は私の選択ですtransactionManagerの?私はJOTMやAtomikosをスタンドアローンで使う必要があると読んでいましたが、JOTMをSpring 4で使うことはできないと思っています。AtomikosはMavenを使う必要があります。 JTATransactionManagerを使用すると、同じ結果が得られました。

作業溶液

JTAエラーが今朝自体を解決するように見えました。何が起こったのか分かりません。私はその後、私はは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(); 
    } 
を得ていたため、すべての必要なパッケージがLocalContainerEntityManagerFactoryBeanによってスキャンされていたことを確認していた

サービスクラス

+0

Spring用に設定したトランザクションマネージャは何ですか? – dunni

+0

私の設定ファイルを追加しました。上記を参照してください - 残念ですが、shouldaはそれを最初に投稿しました。現時点では、JpaTransactionManagerを使用しています。私のjbossでは、私はjtaTransactionManagerを使用しています。 –

+0

それはもちろん無視されます。あなたは 'EntityManagerFactory'を設定していて、それを使用していません。基本的にあなたの全体の構成は役に立たない。 'getEntityManager()'メソッドを削除し、 '@PeristenceContext'を' Private EntityManager'フィールドに置きます。どのようにして最初に 'EntityManager'を取得するのでしょうか。あなたのコードは 'EntityManager'を1回だけ取得し、トランザクションにバインドされていないので危険です。 –

答えて

1

取引が正常に動作している

@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()メソッドを削除し、代わりに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); 
    } 
} 

これですべてが必要です。

+0

正解です。ここにその理由があります。 'Transactional'はContainer Managed EntityManager *としか動作しません。つまり、@ PersistenceContextを使ってSpring(またはJavaEE)によって注入されたものを意味します。 'EntityManagerFactory.createEntityManager()'を呼び出すことによってそれを作成するアプリケーションマネージドEntityManager *がある場合、あなたのコードはトランザクションを管理し、 'EntityManager.getTransaction()。begin()'と ' EntityManager.getTransaction()。commit() ' –

+0

ヒントの人に感謝します。私はフォローアップの質問で上記のいくつかの更新を掲載しました。注意事項 - Klaus、私は実際にトランザクションを明示的に開始またはコミットすることなく、過去にEntityManagerFactory.createEntityManagerを使用することができました。私はちょうど注釈を使用しました。 –

関連する問題