Can't resolve reference to additional datasource during testing

I recently added an additional MySQL datasource to my CUBA project. All seemed to go well – app.properties, portal-app.properties, portal-spring.xml, spring.xml and web-spring.xml were all appended with the new datasource properties. A new persistence unit was created. I added my new entity classes. Tomcat starts – no complaints. However now when I run my test classes I get the following;

08:37:45.734 INFO  com.haulmont.cuba.testsupport.TestContainer - Starting test container io.cfreactor.elements.crm.ElTestContainer$Common@29eee203
08:37:45.805 INFO  com.haulmont.cuba.core.sys.AppComponents - Using app components: [com.haulmont.cuba]
08:37:46.139 INFO  com.haulmont.cuba.core.sys.persistence.PersistenceConfigProcessor - Creating file /Users/dkurz/studio-projects/elements-crm/modules/core/test-home/cuba/work/persistence.xml
08:37:46.208 INFO  com.haulmont.cuba.core.sys.persistence.PersistenceConfigProcessor - Creating file /Users/dkurz/studio-projects/elements-crm/modules/core/test-home/cuba/work/elBeRci-persistence.xml
08:37:46.327 INFO  com.haulmont.cuba.core.sys.CubaCoreApplicationContext - Refreshing com.haulmont.cuba.core.sys.CubaCoreApplicationContext@3a340968: startup date [Tue Oct 31 08:37:46 EDT 2017]; root of context hierarchy
08:37:53.106 DEBUG com.haulmont.cuba.core.sys.CubaJndiDataSourceFactoryBean - Located object with JNDI name [java:comp/env/jdbc/CubaDS]
08:41:12.502 DEBUG com.haulmont.cuba.core.sys.CubaJndiObjectFactoryBean - Converted JNDI name [java:comp/env/jdbc/elBeRci] not found - trying original name [jdbc/elBeRci]. javax.naming.NamingException: Not bound: java:comp/env/jdbc/elBeRci
08:41:12.506 WARN  com.haulmont.cuba.core.sys.CubaCoreApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory_elBeRci' defined in class path resource 
[io/cfreactor/elements/crm/spring.xml]: Cannot resolve reference to bean 'cubaDataSource_elBeRci' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cubaDataSource_elBeRci' defined in class path resource [io/cfreactor/elements/crm/spring.xml]: Invocation of init method failed; nested exception is javax.naming.NamingException: Not bound: jdbc/elBeRci
io.cfreactor.elements.crm.extension.be.rci.service.RciDataServiceBeanTest > classMethod FAILED
org.springframework.beans.factory.BeanCreationException
    Caused by: org.springframework.beans.factory.BeanCreationException
        Caused by: javax.naming.NamingException

Are there some additional steps that I must follow after creating the new datasource in Studio to make it available in my test environment?

Update: Found the TestContainer class will only initialize a single datasource. I did a simple override on the initDataSources() method and included the second datasource. My test classes are now working. Looks like the TestContainer loads multiple persistence configurations but only creates a single datasource.

Hi David,

Thank you for reporting the issue.
TestContainer generated by Studio does not initialize additional datasources indeed. We’ll add it to the docs.

1 Like

With CUBA studio 6.10.1 I have this kind o error …
Please can you share details of your solution ?

Thanks

	... 51 more
Caused by: javax.naming.NamingException: Not bound: jdbc/DBFatturaEl
	at com.haulmont.cuba.testsupport.TestContext.lookup(TestContext.java:48)
	at javax.naming.InitialContext.lookup(InitialContext.java:417)
	at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:155)
	at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
	at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
	at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179)
	at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:104)
	at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:106)
	at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:231)
	at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:217)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1692)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1630)
	... 58 more

In your test container, e.g. com.company.sample.SampleTestContainer class, add the following method:

@Override
protected void initDataSources() {
    super.initDataSources();
    try {
        Class.forName("org.postgresql.Driver"); // your database driver, see modules/core/web/META-INF/context.xml
        TestDataSource ds = new TestDataSource("jdbc:postgresql://localhost/my_additional_database", "db_user", "db_password");
        TestContext.getInstance().bind("jdbc/DBFatturaEl", ds);
    } catch (ClassNotFoundException | NamingException e) {
        throw new RuntimeException("Error initializing datasource", e);
    }
}

Also, if the additional database type is different from the main one, you should add its driver as the testRuntime dependency to core module in build.gradle, for example:

configure(coreModule) {
    // ...
    dependencies {
        // ...
        testRuntime(hsql)
        jdbc('org.postgresql:postgresql:9.4.1212')
        testRuntime('org.postgresql:postgresql:9.4.1212') // add this
    }

Regards,
Konstantin

1 Like

thank you very much

Now the gradle assemble command goes OK !

Massimo