Multiple databases + JNDI with Spring data JPA to initialize
Asked Answered
B

1

0

I want to manage mutiple DataSource using your Application Servers built-in features and access it using JNDI. I am using Spring boot with Spring JPA data. I am able to configure the application.properties for single datasource. But while trying to do the same for mutiple datasource, I am getting an exception while starting the application.

Exception while starting the tomcat server:-

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1902f8f': Cannot resolve reference to bean 'entityManagerFactory' while settin
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:444)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)
        ... 115 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1168)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:281)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
        ... 123 more

Please find below the code samples

Properties file has the below configuration:-

datasource.primary.jndi-name=jdbc/employee
datasource.primary.expected-type=javax.sql.DataSource
datasource.secondary.jndi-name=jdbc/customer
datasource.secondary.expected-type=javax.sql.DataSource

I am sure on the configuration in context.xml file:-

 <Resource name="jdbc/customer" auth="Container" type="javax.sql.DataSource"
                   maxTotal="100" maxIdle="30" maxWaitMillis="10000"
                   username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost:3306/customer"/>

 <Resource name="jdbc/employee" auth="Container" type="javax.sql.DataSource"
                   maxTotal="100" maxIdle="30" maxWaitMillis="10000"
                   username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost:3306/employee"/>

Added the below to Spring boot config class:-

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class })

Customer configuration class:-

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    basePackages = "dao.repository.customer",
    entityManagerFactoryRef = "customerEntityManager", 
    transactionManagerRef = "customerTransactionManager"
)
public class customerConfig {


    @Bean
    public LocalContainerEntityManagerFactoryBean customerEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(customerDataSource());
        em.setPackagesToScan(new String[] { "dao.entity.customer" });
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        return em;
    }

    @Bean
    @ConfigurationProperties(prefix = "datasource.secondary")
    public DataSource customerDataSource() {
      final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
      dsLookup.setResourceRef(true);
      DataSource dataSource = dsLookup.getDataSource("jdbc/customer");
      return dataSource;

    }

    @Bean
    public PlatformTransactionManager customerTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(customerEntityManager().getObject());
        return transactionManager;
    }
}

The employee configuartion class

 @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
        basePackages = "dao.repository.employee",
        entityManagerFactoryRef = "employeeEntityManager", 
        transactionManagerRef = "employeeTransactionManager"
    )
    public class employeeConfig {


        @Bean
        @Primary
        public LocalContainerEntityManagerFactoryBean employeeEntityManager() {
            LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
            em.setDataSource(employeeDataSource());
            em.setPackagesToScan(new String[] { "dao.entity.employee" });
            HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            em.setJpaVendorAdapter(vendorAdapter);
            return em;
        }

        @Bean
        @Primary
        @ConfigurationProperties(prefix = "datasource.primary")
        public DataSource employeeDataSource() {
          final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
          dsLookup.setResourceRef(true);
          DataSource dataSource = dsLookup.getDataSource("jdbc/employee");
          return dataSource;

        }

        @Bean
        @Primary
        public PlatformTransactionManager employeeTransactionManager() {
            JpaTransactionManager transactionManager = new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(employeeEntityManager().getObject());
            return transactionManager;
        }
    }

In the entity classes I am mentioning the schema name.

@Entity
@Table(schema="customer")
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
.........
}

@Entity
 @Table(schema="employee")

 public class Project implements Serializable {
    .........
 }

Update

I have moved a bit more on this but still not resolved.

Caused by: net.spy.memcached.OperationTimeoutException: Mutate operation timed out,unable to modify counter [validator.validatorCache.HibernateCacheTimestamperMemcachedImpl:timestamp]
        at net.spy.memcached.MemcachedClient.mutate(MemcachedClient.java:1663) ~[spymemcached-2.10.2.jar:2.10.2]
        at net.spy.memcached.MemcachedClient.mutateWithDefault(MemcachedClient.java:1835) ~[spymemcached-2.10.2.jar:2.10.2]
        at net.spy.memcached.MemcachedClient.incr(MemcachedClient.java:1767) ~[spymemcached-2.10.2.jar:2.10.2]
        at kr.pe.kwonnam.hibernate4memcached.spymemcached.SpyMemcachedAdapter.increaseCounter(SpyMemcachedAdapter.java:185) ~[hibernate4-memcached-spymemcached-adapter-0.7.jar:na]
        at kr.pe.kwonnam.hibernate4memcached.timestamper.HibernateCacheTimestamperMemcachedImpl.next(HibernateCacheTimestamperMemcachedImpl.java:59) ~[hibernate4-memcached-core-0.7.jar:na]
        at kr.pe.kwonnam.hibernate4memcached.Hibernate4MemcachedRegionFactory.nextTimestamp(Hibernate4MemcachedRegionFactory.java:127) ~[hibernate4-memcached-core-0.7.jar:na]
        at org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1589) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.internal.EntityManagerImpl.internalGetSession(EntityManagerImpl.java:141) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.internal.EntityManagerImpl.isOpen(EntityManagerImpl.java:165) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.internal.EntityManagerImpl.checkOpen(EntityManagerImpl.java:101) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.internal.EntityManagerImpl.checkOpen(EntityManagerImpl.java:96) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.internal.EntityManagerImpl.getSession(EntityManagerImpl.java:111) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.setDefaultProperties(AbstractEntityManagerImpl.java:308) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:213) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.internal.EntityManagerImpl.<init>(EntityManagerImpl.java:91) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.internal.EntityManagerFactoryImpl.internalCreateEntityManager(EntityManagerFactoryImpl.java:345) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.internal.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_20]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_20]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_20]
        at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_20]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:388) ~[spring-orm-4.0.9.RELEASE.jar:4.0.9.RELEASE]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:541) ~[spring-orm-4.0.9.RELEA
        at com.sun.proxy.$Proxy558.createEntityManager(Unknown Source) ~[na:na]
        at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:285) ~[spring-orm-4.0.9.RELEASE.jar:4.0.9.RELEASE
        at com.sun.proxy.$Proxy559.getDelegate(Unknown Source) ~[na:na]
        at org.springframework.data.jpa.provider.JpaClassUtils.isEntityManagerOfType(JpaClassUtils.java:46) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
        at org.springframework.data.jpa.provider.PersistenceProvider.fromEntityManager(PersistenceProvider.java:296) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.<init>(JpaRepositoryFactory.java:57) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.createRepositoryFactory(JpaRepositoryFactoryBean.java:79) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.doCreateRepositoryFactory(JpaRepositoryFactoryBean.java:69) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
        at org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport.createRepositoryFactory(TransactionalRepositoryFactoryBeanSupport.java:72) ~[spring-data-
        at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:216) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.REL
        ... 112 common frames omittedenter code here
    enter code here

I am setting the bwlo properties to LocalContainerEntityManagerFactoryBean object:-

 HashMap<String, Object> properties = new HashMap<String, Object>();        
    properties.put("hibernate.hbm2ddl.auto", "validate");
    properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");

    properties.put("hibernate.cache.use_second_level_cache", "true");
    properties.put("hibernate.cache.use_query_cache", "true");
    properties.put("hibernate.cache.region.factory_class", "kr.pe.kwonnam.hibernate4memcached.Hibernate4MemcachedRegionFactory");
    properties.put("hibernate.cache.default_cache_concurrency_strategy", "NONSTRICT_READ_WRITE");
    properties.put("hibernate.cache.region_prefix", "userPersistenceUnit");
    properties.put("hibernate.cache.use_structured_entries", "false");
    properties.put("h4m.adapter.class", "kr.pe.kwonnam.hibernate4memcached.spymemcached.SpyMemcachedAdapter");
    properties.put("h4m.timestamper.class", "kr.pe.kwonnam.hibernate4memcached.timestamper.HibernateCacheTimestamperMemcachedImpl");

    properties.put("h4m.adapter.spymemcached.hosts", "localhost:11211");
    properties.put("h4m.adapter.spymemcached.hashalgorithm", "KETAMA_HASH");
    properties.put("h4m.adapter.spymemcached.operation.timeout.millis", "5000");
    properties.put("h4m.adapter.spymemcached.transcoder", "kr.pe.kwonnam.hibernate4memcached.spymemcached.KryoTranscoder");
    properties.put("h4m.adapter.spymemcached.cachekey.prefix", "validator");
    properties.put("h4m.adapter.spymemcached.kryotranscoder.compression.threashold.bytes", "20000");


    properties.put("h4m.expiry.seconds", "600");
    properties.put("h4m.expiry.seconds.userPersistenceUnit.org.hibernate.cache.spi.UpdateTimestampsCache", "86400");
    properties.put("h4m.expiry.seconds.userPersistenceUnit.org.hibernate.cache.internal.StandardQueryCache", "3600");
    properties.put("h4m.expiry.seconds.userPersistenceUnit.users", "1800");
    properties.put("h4m.expiry.seconds.userPersistenceUnit.certificates", "1800");

Update -II

Memcahe is up and running..

C:\windows\system32>netstat -na | find "11211"
  TCP    0.0.0.0:11211          0.0.0.0:0              LISTENING
  TCP    [::]:11211             [::]:0                 LISTENING
  UDP    0.0.0.0:11211          *:*

Application log that shows that memcached is running.

    16:20:25.893 [localhost-startStop-7] DEBUG u.c.o.s.v.d.config.CertificateConfig - Creating certificateDataSource
{h4m.expiry.seconds.userPersistenceUnit.users=1800, hibernate.hbm2ddl.auto=validate, h4m.adapter.spymemcached.operation.timeout.millis=5000, hibernate.dialect=org.hibernate.dialect.MySQL5Dialect, hibernate.cache.use_structured_entries=false, hibernate.cache.use_query_cache=true, h4m.expiry.seconds.userPersistenceUnit.certificates=1800, h4m.adapter.spymemcached.kryotranscoder.compression.threashold.bytes=20000, h4m.adapter.spymemcached.hashalgorithm=KETAMA_HASH, h4m.adapter.class=kr.pe.kwonnam.hibernate4memcached.spymemcached.SpyMemcachedAdapter, hibernate.cache.default_cache_concurrency_strategy=NONSTRICT_READ_WRITE, h4m.adapter.spymemcached.cachekey.prefix=validatorUser, h4m.adapter.spymemcached.hosts=localhost:11211, hibernate.cache.use_second_level_cache=true, hibernate.cache.region_pre
fix=userPersistenceUnit, h4m.timestamper.class=kr.pe.kwonnam.hibernate4memcached.timestamper.HibernateCacheTimestamperMemcachedImpl, hibernate.cache.region.factory_class=kr.pe.kwonnam.hibernate4memcached.Hibernate4MemcachedRegionFactory, h4m.expiry.seconds.userPersistenceUnit.org.hibernate.cache.internal.StandardQueryCache=3600, h4m.expiry.seconds.userPersistenceUnit.org.hibernate.cache.spi.UpdateTimestampsCache=86400, h4m.expiry.seconds=600, h4m.adapter.spymemcached.transcoder=kr.pe.kwonnam.hibernate4memcached.spymemcached.KryoTranscoder}
16:20:26.201 [localhost-startStop-7] INFO  o.s.o.j.LocalContainerEntityManagerFactoryBean - Building JPA container EntityManagerFactory for persistence unit 'userPersistenceUnit'
16:20:26.242 [localhost-startStop-7] INFO  o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [
        name: userPersistenceUnit
        ...]
16:20:26.502 [localhost-startStop-7] INFO  org.hibernate.Version - HHH000412: Hibernate Core {4.3.8.Final}
16:20:26.506 [localhost-startStop-7] INFO  org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found
16:20:26.511 [localhost-startStop-7] INFO  org.hibernate.cfg.Environment - HHH000021: Bytecode provider name : javassist
16:20:27.193 [localhost-startStop-7] INFO  o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
16:20:27.657 [localhost-startStop-7] INFO  org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
16:20:28.223 [localhost-startStop-7] INFO  o.h.h.i.a.ASTQueryTranslatorFactory - HHH000397: Using ASTQueryTranslatorFactory
2015-11-26 16:20:28.412 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=localhost/127.0.0.1:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2015-11-26 16:20:28.427 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@1da36e8
16:20:28.432 [localhost-startStop-7] INFO  o.h.cache.spi.UpdateTimestampsCache - HHH000250: Starting update timestamps cache at region: userPersistenceUnit.org.hibernate.cache.spi.UpdateTimestampsCache
16:20:28.438 [localhost-startStop-7] INFO  k.p.k.h.r.GeneralDataMemcachedRegion - expirySeconds of cache region [userPersistenceUnit.org.hibernate.cache.spi.UpdateTimestampsCache] - 86400 seconds.
16:20:28.443 [localhost-startStop-7] INFO  o.h.c.internal.StandardQueryCache - HHH000248: Starting query cache at region: userPersistenceUnit.org.hibernate.cache.internal.StandardQueryCache
16:20:28.445 [localhost-startStop-7] INFO  k.p.k.h.r.GeneralDataMemcachedRegion - expirySeconds of cache region [userPersistenceUnit.org.hibernate.cache.internal.StandardQueryCache] - 3600 seconds.
16:20:28.745 [localhost-startStop-7] INFO  k.p.k.h.r.GeneralDataMemcachedRegion - expirySeconds of cache region [userPersistenceUnit.users] - 1800 seconds.
16:20:28.973 [localhost-startStop-7] INFO  k.p.k.h.r.GeneralDataMemcachedRegion - expirySeconds of cache region [userPersistenceUnit.users] - 1800 seconds.
16:20:29.021 [localhost-startStop-7] INFO  k.p.k.h.r.GeneralDataMemcachedRegion - expirySeconds of cache region [userPersistenceUnit.users] - 1800 seconds.
16:20:29.024 [localhost-startStop-7] INFO  k.p.k.h.r.GeneralDataMemcachedRegion - expirySeconds of cache region [userPersistenceUnit.users] - 1800 seconds.
16:20:29.328 [localhost-startStop-7] INFO  o.h.tool.hbm2ddl.SchemaValidator - HHH000229: Running schema validator
16:20:29.329 [localhost-startStop-7] INFO  o.h.tool.hbm2ddl.SchemaValidator - HHH000102: Fetching database metadata
16:20:29.374 [localhost-startStop-7] INFO  o.h.tool.hbm2ddl.TableMetadata - HHH000261: Table found: user.roleprivilege

I also stoped memcached and tried, then i am getting connection failure log while starting the application.

Belak answered 17/11, 2015 at 22:9 Comment(0)
E
0

Did you try to add something like this:

    Properties p = new Properties();
    p.put("hibernate.ejb.entitymanager_factory_name", "customerEntityManager");
    em.setJpaProperties(p);

or similar from application.properties if you can?

Expanse answered 24/11, 2015 at 0:19 Comment(9)
No luck. Still getting the error the same. Added it to properties. I am adding everything to properties for both the entity instances (customerEntityManager and employeEntityManager).Belak
Caused by: net.spy.memcached.OperationTimeoutException: Mutate operation timed out,unable to modify counter [validator.validatorCache.HibernateCacheTimestamperMemcachedImpl:timestamp]Belak
Well, similar problem to that one you mentioned last is described here. Try to exclude memcached from your project for start. Did I get it right that you do not have same error again (NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined) but only this new one?Expanse
Yes.I a moved a bit from the earlier error. Now its a pure memcached problem. I am able to load the application succesfully if i remove all the memcache code.I have updated the question with the latest error message.Belak
Are you sure your memcache server is available (localhost:11211)? As I pointed out earlier, here is this useful comment: I couldn't connect at all [...] it had no memcached server to perform...Expanse
Yes memcached is up and running.I will put the details in question.Belak
Also from the logs you can see the properties I am setting. I was able to make it work, with sigle datasource. I am getting the problem, when i had two datasource.I checked the mutiple datasource code, without memcached also, just to be sure that the memcached is causing the issue.Belak
Could be relevant: How can we create two instances of memcached server in same server in different port?.Expanse
Let us continue this discussion in chat.Belak

© 2022 - 2024 — McMap. All rights reserved.