Page 2 of 2 FirstFirst 12
Results 11 to 19 of 19

Thread: Transforming JPA related beans to JavaConfig

  1. #11
    Join Date
    Apr 2007
    Posts
    307

    Default

    There is no equivalent as yet to jee:jndi-lookup, though it is planned for. It would be helpful if you would create a feature request in JIRA for this. You can follow the example of http://jira.springframework.org/browse/SJC-96 when you do this.

    In the meantime, you can directly use http://static.springframework.org/sp...ctoryBean.html. This is a more low-level approach, but will work just fine.
    Chris Beams
    Spring Framework committer, VMware
    http://github.com/cbeams

  2. #12
    Join Date
    Aug 2008
    Location
    Billings, Montana
    Posts
    47

    Default

    Chris,

    I submitted a reply and it did not show up till now. So re-posting it.

    I logged a JIRA for this issue (jira.springframework.org/browse/SJC-197).

    Do you think the following should work?

    Code:
      public @Bean EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setPersistenceUnitName("flux");
        em.setJpaProperties(getJpaProperties());
        em.setDataSource(jndiDataSource());
        em.setJpaVendorAdapter(jpaVendorAdapter());
        em.setLoadTimeWeaver(loadTimeWeaver());
        return (EntityManagerFactory) this.getObject(em);
      }
    
      public @Bean DataSource jndiDataSource() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("java:comp/env/jdbc/MySqlDataSource");
        jndiObjectFactoryBean.setCache(true);
        jndiObjectFactoryBean.setLookupOnStartup(false);
        jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
        return (DataSource) this.getObject(jndiObjectFactoryBean);
      }
    Thanks!
    Arul

  3. #13
    Join Date
    Apr 2007
    Posts
    307

    Default

    At a glance, yes it should work. Also note that ConfigurationSupport.getObject() now has a generics-enabled variant. See the last line below (saves you the cast):

    public @Bean DataSource jndiDataSource() {
    JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
    jndiObjectFactoryBean.setJndiName("java:comp/env/jdbc/MySqlDataSource");
    jndiObjectFactoryBean.setCache(true);
    jndiObjectFactoryBean.setLookupOnStartup(false);
    jndiObjectFactoryBean.setProxyInterface(javax.sql. DataSource.class);
    return this.getObject(jndiObjectFactoryBean, DataSource.class);
    }
    Chris Beams
    Spring Framework committer, VMware
    http://github.com/cbeams

  4. #14
    Join Date
    Aug 2008
    Location
    Billings, Montana
    Posts
    47

    Default

    Thanks Chris for the tip.

    I currently have the following bean configurations.

    Code:
      @Bean
      public DataSource dataSource() {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        try {
          dataSource.setDriverClass(driverClass());
        } catch (PropertyVetoException pve) {
    
        }
        dataSource.setJdbcUrl(jdbcUrl());
        dataSource.setUser(user());
        dataSource.setPassword(password());
        dataSource.setMinPoolSize(minPoolSize());
        dataSource.setAcquireIncrement(acquireIncrement());
        dataSource.setMaxPoolSize(maxPoolSize());
        return dataSource;
      }
    
      @Bean
      public DataSource jndiDataSource() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName(dataSourceJndiName());//dynamic
        jndiObjectFactoryBean.setCache(true);
        jndiObjectFactoryBean.setLookupOnStartup(false);
        jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
        return this.getObject(jndiObjectFactoryBean, DataSource.class);
      }
    Is it possible to dynamically use one of these configuration at runtime? If the user provide standalone datasource, I need to use dataSource() config. If the user provides jndi datasource, I need to use jndiDataSource() config.

    Please clarify.

  5. #15
    Join Date
    Aug 2008
    Location
    Billings, Montana
    Posts
    47

    Default

    I have the following bean configuration.

    Code:
    @EnvironmentValueSource
    @Configuration
    public abstract class ApplicationConfiguration {
    
        abstract
        @ExternalValue("database_type")
        String databaseType();
    }
    
    @Configuration
    @AnnotationDrivenTx
    @PropertiesValueSource(locations = "classpath:config.properties")
    @Import({DataSourceConfiguration.class, ApplicationConfiguration.class})
    @ComponentScan({"dao.impl", "service.impl"})
    public abstract class JpaConfiguration extends ConfigurationSupport {
    
        abstract
        @ExternalBean
        String databaseType();
        //omitted other methods for clarity
    }
    I am getting the following error when I try to access the bean which uses databaseType(). I have imported the external bean too. Not sure what I am missing here.

    Code:
    Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public final java.lang.String config.JpaConfiguration$$EnhancerByCGLIB$$7c12f771.databasePlatform()] threw exception; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'databaseType' is defined
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:127)
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:435)
    	... 147 more
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'databaseType' is defined
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:387)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:968)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:246)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:168)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:238)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
    	at org.springframework.config.java.internal.enhancement.CglibConfigurationEnhancer$ExternalBeanMethodInterceptor.doIntercept(CglibConfigurationEnhancer.java:188)
    	at org.springframework.config.java.internal.enhancement.CglibConfigurationEnhancer$AbstractMethodInterceptor.intercept(CglibConfigurationEnhancer.java:170)
    	at config.JpaConfiguration$$EnhancerByCGLIB$$7c12f771.databaseType(<generated>)
    	at config.JpaConfiguration.databasePlatform(JpaConfiguration.java:146)
    	at config.JpaConfiguration$$EnhancerByCGLIB$$7c12f771.CGLIB$databasePlatform$21(<generated>)
    	at config.JpaConfiguration$$EnhancerByCGLIB$$7c12f771$$FastClassByCGLIB$$d9791c9c.invoke(<generated>)
    	at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:167)
    	at org.springframework.config.java.internal.enhancement.CglibConfigurationEnhancer$BeanMethodInterceptor.doIntercept(CglibConfigurationEnhancer.java:285)
    	at org.springframework.config.java.internal.enhancement.CglibConfigurationEnhancer$AbstractMethodInterceptor.intercept(CglibConfigurationEnhancer.java:170)
    	at config.JpaConfiguration$$EnhancerByCGLIB$$7c12f771.databasePlatform(<generated>)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:585)
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:115)
    	... 148 more
    Appreciate any help.

    Thanks!
    Arul

  6. #16
    Join Date
    Apr 2007
    Posts
    307

    Default

    Arul,

    @ExternalValue methods are not registered as beans, so they will not be resolved by trying to reference them with @ExternalBean.

    I understand what you're trying to do here, but it's not supported. Feel free to add a request in JIRA so we can keep tabs on this.

    In the meantime, one option would be to use a base class approach:

    Code:
    @Configuration
    @EnvironmentVariableSource
    public class BaseConfig {
        protected @ExternalValue("database_type") String databaseType;
    }
    
    @Configuration
    public class ConcreteConfig extends BaseConfig {
        public @Bean Foo beanThatNeedsDatabaseType() {
            return new Foo(this.databaseType);
        }
    }
    Chris Beams
    Spring Framework committer, VMware
    http://github.com/cbeams

  7. #17
    Join Date
    Apr 2007
    Posts
    307

    Default

    Also, please post any future new questions in a new forum thread so that others can easily find answers to similar questions.
    Chris Beams
    Spring Framework committer, VMware
    http://github.com/cbeams

  8. #18
    Join Date
    Aug 2008
    Location
    Billings, Montana
    Posts
    47

    Default

    Thanks Chris. I will post my further questions in new forum thread.

  9. #19
    Join Date
    Aug 2008
    Location
    Billings, Montana
    Posts
    47

    Default

    Created a JIRA for this issue: jira.springframework.org/browse/SJC-198

    Thanks!
    Arul

    Quote Originally Posted by Chris Beams View Post
    Arul,

    @ExternalValue methods are not registered as beans, so they will not be resolved by trying to reference them with @ExternalBean.

    I understand what you're trying to do here, but it's not supported. Feel free to add a request in JIRA so we can keep tabs on this.

    In the meantime, one option would be to use a base class approach:

    Code:
    @Configuration
    @EnvironmentVariableSource
    public class BaseConfig {
        protected @ExternalValue("database_type") String databaseType;
    }
    
    @Configuration
    public class ConcreteConfig extends BaseConfig {
        public @Bean Foo beanThatNeedsDatabaseType() {
            return new Foo(this.databaseType);
        }
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •