Multiple datasources with Grails 3.1.5 and Postgresql - postgresql

I am trying to connect to two postgresql databases from a single Grails 3.1.5 application, my application.yml looks like this:
hibernate:
cache:
queries: false
use_second_level_cache: true
use_query_cache: false
region.factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory
dataSources:
dataSource:
pooled: true
jmxExport: true
driverClassName: org.postgresql.Driver
username: username
password: password
dialect: net.kaleidos.hibernate.PostgresqlExtensionsDialect
dataSource_two:
pooled: true
jmxExport: true
driverClassName: org.postgresql.Driver
username: username
password: password
dialect: net.kaleidos.hibernate.PostgresqlExtensionsDialect
environments:
development:
dataSources:
dataSource:
dbCreate: update
url: jdbc:postgresql://localhost:5432/dbone
dataSource_two:
dbCreate: update
url: jdbc:postgresql://localhost:5432/dbtwo
test:
dataSource:
dbCreate: update
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
production:
dataSource:
dbCreate: update
url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
I am getting this error and cannot start the application
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'transactionManager_dataSource_two' while setting constructor argument with key [1]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager_dataSource_two': Cannot resolve reference to bean 'sessionFactory_dataSource_two' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory_dataSource_two': Invocation of init method failed; nested exception is org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given; please either disable second level cache or set correct region factory using the hibernate.cache.region.factory_class setting and make sure the second level cache provider (hibernate-infinispan, e.g.) is available on the classpath.
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.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:382)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:157)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.grails.transaction.TransactionManagerPostProcessor.initialize(TransactionManagerPostProcessor.java:75)
at org.grails.transaction.TransactionManagerPostProcessor.setBeanFactory(TransactionManagerPostProcessor.java:53)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1597)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1565)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
... 20 common frames omitted
Looks like grails cannot find hibernate.cache.region.factory_class but as you can see I have that property in application.yml. I also checked if the class exists in classpath and it does. Any ideas why I am getting this error ?

the hibernate settings are datasource-specific, too.
so try adding a hibernate_two block with the hibernate settings for your dataSource_two

I updated the grails version to 3.1.9 and used the same exact configuration and it worked. The only thing I changed is was 'org.hibernate.cache.ehcache.EhCacheRegionFactory' to 'org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory'.

Related

Micronaut require entities during build

we created new application with JPA configuration. It is new application, so there are no entities yet and application failing during build with this error:
io.micronaut.context.exceptions.ConfigurationException: Entities not found for JPA configuration: 'default' within packages io.example.foo
This error is not error because there really no entity exists. When I created dummy entity to test, build pass. Can you tell me how to fix it?
This is my jpa configuration:
jpa:
default:
properties:
hibernate:
hbm2ddl:
auto: none
dialect: org.hibernate.dialect.PostgreSQL10Dialect
physical_naming_strategy: "io.micronaut.data.hibernate.naming.DefaultPhysicalNamingStrategy"
bytecode:
provider: none

Unable to connect app to postgres server using yaml files

Following Error while connecting springboot app service to Postgres using yml.
NOTE: url: jdbc:postgresql://localhost/postgres
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Cannot create inner bean '(inner bean)#3f0846c6' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#3f0846c6': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:397)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1429)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:636)
... 62 common frames omitted
Caused by: java.net.UnknownHostException: db
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:220)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:591)
at org.postgresql.core.PGStream.<init>(PGStream.java:75)
at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:91)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:192)
... 138 common frames omitted
Please suggest the alternatives and ideas
Well, you did not show your yaml file, that is most important. Error says problem with connection, so make sure your postgres is up and running, you can test it in console like
psql -h localhost -p port(default 5432) -U username -d database
spring:
datasource:
url: jdbc:postgresql://localhost:5432/databaseName?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
username: yourUsername
password: yourPassword
jpa:
hibernate:
ddl-auto: update
show-sql: true
This is example of application.yaml for connecting to postgresql running on your machine, i am using docker for databases,so it works for that as well. Then make sure you have postgresql in your build file. If you use maven, it looks like this
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
And don`t forget JPA, which you probably have, as i see from error, but anyway
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Version is defined as parent. Spring boot makes configuration and connection for you, just by adding dependencies and reading your application.yml file.

how to work with extension created in postgres in spring data jpa

I am new to spring data jpa.
i have a legacy database , which i am trying to connect to via spring data jpa.
i have a certain extension created in postgres which is used for some of the columns in my tables
for e.g
CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public;
this extension is created mostly for (case-insensitive text)
now when i try to map the tables using standard entity annotations, it gives me error, as its unable to understand this extension
The error i get is
g.springframework.boot.SpringApplication - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [domain_obj_nm] in table [attr_grp_defn]; found [citext (Types#OTHER)], but expecting [varchar(255) (Types#VARCHAR)]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1634)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1080)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
at com.sas.mkt.example.app.Application.main(Application.java:43)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [domain_obj_nm] in table [attr_grp_defn]; found [citext (Types#OTHER)], but expecting [varchar(255) (Types#VARCHAR)]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1692)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1630)
... 16 common frames omitted
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [domain_obj_nm] in table [attr_grp_defn]; found [citext (Types#OTHER)], but expecting [varchar(255) (Types#VARCHAR)]
i want a way via annotations to solve this issue, its ok if it is treated just as text column.
Hibernate is validating the schema on start-up as the ddl.auto property is set to validate.
You can either disable validation entirely or specify a column definition for the relevant #Columnproperty which should allow the validation to pass:
https://docs.oracle.com/javaee/5/api/javax/persistence/Column.html#columnDefinition()
#Column(columnDefinition = "citext") //or "other"?
private String myField;
Note that the column definition only affects DDL operations i.e. schema creation or validation.
Disabling validation entirely depends on your set-up. In a spring-boot app for example you set spring.jpa.hibernate.ddl-auto = false

"IllegalArgumentException: Name must not be null" when deploying to jboss

(I already solved this problem, but posting it here to help others.)
I recently upgraded from Grails 2.4.4 to Grails 3. When deploying to JBoss EAP 6.4 (Wildfly 7), I receive the following error in the server log and the application fails to start:
09-06 20:46:18,463 ERROR [org.jboss.as.web.deployment.JBossContextConfig] (ServerService Thread Pool -- 90) JBAS018202: Error calling onStartup for servlet container initializer: org.springframework.web.SpringServletContainerInitializer: java.lang.IllegalArgumentException: Name must not be null
at org.springframework.util.Assert.notNull(Assert.java:115) [spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:214) [spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:284) [spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.grails.transaction.ChainedTransactionManagerPostProcessor.resolveTransactionManagerClass(ChainedTransactionManagerPostProcessor.java:158) [grails-core-3.1.5.jar:3.1.5]
at org.grails.transaction.ChainedTransactionManagerPostProcessor.hasJtaOrChainedTransactionManager(ChainedTransactionManagerPostProcessor.java:143) [grails-core-3.1.5.jar:3.1.5]
at org.grails.transaction.ChainedTransactionManagerPostProcessor.postProcessBeanDefinitionRegistry(ChainedTransactionManagerPostProcessor.java:119) [grails-core-3.1.5.jar:3.1.5]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:123) [spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:678) [spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:520) [spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at grails.boot.GrailsApp.run(GrailsApp.groovy:55) [grails-core-3.1.5.jar:3.1.5]
I have two different data sources in the application, both of which are registered in JNDI.
After running through a debugger, I see that transactionManagerBeanDefinition.getBeanClassName() returns null but I am not sure why.
Why would this error be happening, and how would I solve it?
This link led me to the answer.
The problem seems to be caused by there being multiple datasources in my application, which causes Spring / JBoss to get confused when setting up the transaction manager.
The solution is to set transactional: false in application.yml for the second datasource. This worked perfect for me, since the second datasource is read-only anyway.
application.yml:
dataSources:
dataSource:
dialect: "..."
otherDataSource:
dialect: "..."
transactional: false <------ add this line

Spring-Boot Camel JPA auto configuration

there are a lot of examples of camel and spring dealing with JPA, but I would prefer spring boot autoconfigured data source instead of XML or configuration classes.
However even with
spring:
datasource:
url: jdbc:postgresql://postgres/fooBarBaz
username: fooBarBaz
password: fooBarBaz
jpa:
hibernate:
ddl-auto: update
naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
set up
The data source is not picked up:
No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as auto wire candidate for this dependency.