2013-10-17 6 views
12

新しいSpring 3.2.4アプリケーションの開発を開始しました。過去に使用したようにXMLベースの構成ではなくJavaベースの構成を使用しようとしています。しかし、私は移行に問題があります。 XMLを使用してXML構成の代わりにSpring @Configurationを使用してJNDIを取得する方法

次のように、私はそれをコーディングします。

<!-- application datasource --> 
<bean id="dataSource.jndi" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton" lazy-init="true"> 
    <property name="jndiName" value="java:comp/env/jdbc/liment" /> 
</bean> 

<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory"/> 
</bean> 

<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/> 
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"> 
    <property name="persistenceUnitName" value="persistenceUnit"/> 
    <property name="dataSource" ref="dataSource.jndi"/> 
</bean> 

をしかし、私は非常にJavaでこれを行う方法を把握しようとこだわっています。私は設定を複製しようとしているが、トラブルに実行しているよ:

@Configuration 
@EnableTransactionManagement 
@EnableJpaRepositories(basePackages={"com.ia"}) 
public class AppConfigJPA { 
    @Bean 
    public DataSource dataSource() { 
     // configure and return the necessary JDBC DataSource 
     JndiObjectFactoryBean dataSource = new JndiObjectFactoryBean(); 
     dataSource.setJndiName("java:comp/env/jdbc/liment"); 
     try { 
      dataSource.afterPropertiesSet(); 
     } catch (IllegalArgumentException | NamingException e) { 
      // rethrow 
      throw new RuntimeException(e); 
     } 
     return (DataSource)dataSource.getObject(); 
    } 

    @Bean 
    public EntityManagerFactory entityManagerFactory(){ 
     LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); 
     emf.setPersistenceUnitName("persistenceUnit"); 
     emf.setDataSource(dataSource()); 
      emf.afterPropertiesSet 
     return emf.getObject(); 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager() { 
     return new JpaTransactionManager(entityManagerFactory()); 
    } 

} 

しかし、私は次のようなエラーメッセージが出ます:

Caused by: java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation. 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:142) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.setBeanFactory(PersistenceExceptionTranslationInterceptor.java:117) 
    at org.springframework.data.repository.core.support.PersistenceExceptionTranslationRepositoryProxyPostProcessor.<init>(PersistenceExceptionTranslationRepositoryProxyPostProcessor.java:44) 
    at org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport.setBeanFactory(TransactionalRepositoryFactoryBeanSupport.java:85) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1502) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1470) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521) 
    ... 33 more 

は、私が何をしないか、間違っているのですが?

@SotiriosDelimanolis応答の後EDIT

は、私は次のように読み取るために自分のコードを変更した:

@Autowired DataSource dataSource; 
@Autowired EntityManagerFactory entityManagerFactory; 


@Bean 
public JndiObjectFactoryBean dataSource() { 
    // configure and return the necessary JDBC DataSource 
    JndiObjectFactoryBean dataSource = new JndiObjectFactoryBean(); 
    dataSource.setJndiName("java:comp/env/jdbc/josak"); 
    return dataSource; 
} 

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){ 
    LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); 
    emf.setPersistenceUnitName("persistenceUnit"); 
    emf.setDataSource(dataSource); 
    return emf; 
} 

@Bean 
public PlatformTransactionManager transactionManager() { 
    return new JpaTransactionManager(entityManagerFactory); 
} 

しかし、今は代わりにAutowired例外を取得しています:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: javax.sql.DataSource com.ia.system.configuration.AppConfigJPA.dataSource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) 
    ... 31 more 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486) 
    ... 33 more 
+0

あなたは参照が 'dataSource.getObject()によって返されたことを確認することができ;'です'ヌル'?これは 'afterPropertiesSet()'を呼び出した場合には起こらないはずです。そして、より長いスタックトレースを投稿してください。 –

+0

@SotiriosDelimanolis実際、あなたのコメントを見る前に、私はちょうどコードの間違いを犯しました。私は、entityManagerFactory()の "afterPropertiesSet()"呼び出しを忘れていました。しかし、今では、永続性例外トランスレータに関する別の例外が発生します。 –

答えて

1

これは奇妙なデザイン(PersistenceExceptionTranslator用)ですmediately理解するが、ここに解決策がある。

お客様のLocalContainerEntityManagerFactoryBeanFactoryBeanですが、PersistenceExceptionTranslator(両方とも実装)です。しかし、あなたは自分のコンテキストにLocalContainerEntityManagerFactoryBeanを入れておらず、作成されたオブジェクトのみを取得しています。

代わりの

@Bean 
public EntityManagerFactory entityManagerFactory(){ 
    LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); 
    emf.setPersistenceUnitName("persistenceUnit"); 
    emf.setDataSource(dataSource()); 
     emf.afterPropertiesSet 
    return emf.getObject(); 
} 

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){ 
    LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); 
    emf.setPersistenceUnitName("persistenceUnit"); 
    emf.setDataSource(dataSource()); 
    return emf; 
} 

@Autowired 
private EntityManagerFactory entityManagerFactory; 

@Bean 
public PlatformTransactionManager transactionManager() { 
    return new JpaTransactionManager(entityManagerFactory); 
} 

を行う春はコンテキストにEntityManagerFactory豆を入れてafterPropertiesSet()getObject()を呼び出すの世話をします。

基本的に、2つの豆、EntityManagerFactory、およびLocalContainerEntityManagerFactoryBeanで終了します。 JPA構成では、コンテキスト内でPersistenceExceptionTranslator Beanが必要です。それはLocalContainerEntityManagerFactoryBeanによって満足されます。


FYI、あなたのJndiObjectFactoryBeanやその他のFactoryBeanのために同じことを行うことができます。

+0

JpaTransactionManagerは、コンストラクタタイプとしてEntityManagerFactoryが必要です。 entityManagerFactory()がLocalContainerEntityManagerFactoryBeanを返す場合、transactionManager()をインスタンス化するにはどうすればよいですか?同様に、dataSource()からJndiObjectFactoryBeanを返した場合、どのようにしてemf.setDataSource()をJndiFactoryBeanで設定しますか? –

+0

@ EricB。春はそのように魔法です。それは '@ Bean'メソッド呼び出しを代行し、' FactoryBean'自体の代わりに 'FactoryBean'が作成したbeanを返します。 –

+0

私は分かりません。ファクトリBeanを返すと、コンパイラは 'return new JpaTransactionManager(entityManagerFactory())'に対してコンパイラを不平にします: 'コンストラクタJpaTransactionManager(LocalContainerEntityManagerFactoryBean)は 未定義' –

20

リンクの下に参照してください -

http://forum.spring.io/forum/spring-projects/container/724356-how-to-use-javaconfig-to-declare-a-jndi-datasource

データソースは、次のように作成する必要がある -

@Bean 
    public DataSource dataSource() { 
     final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); 
     dsLookup.setResourceRef(true); 
     DataSource dataSource = dsLookup.getDataSource("jdbc/yourJdbcGoesHere"); 
     return dataSource; 
    } 
+1

JndiDataSourceLookupはtrueに設定するので、このコンテキストでは 'setResourceRef'は必要ありません。コードは単純に 'new JndiDataSourceLookup()。getDataSource(" jdbc/yourJdbcGoesHere ")' – Brice

関連する問題