Exception while connecting spring data config to IBM DB2 z/os - spring

I am getting the following exception while bringing up the spring boot app(app doesnt not have any code just the DB related configs and connection parameters which are defined in the application.properties file)
Could not fetch the SequenceInformation from the database
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=SYSCAT.SEQUENCES, DRIVER=4.19.49
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>db2.jcc</groupId> <!-- internal from private repo -->
<artifactId>db2jcc_license_cu</artifactId>
<version>4.19.49</version>
</dependency>
<dependency>
<groupId>db2.jcc</groupId> <!-- internal from private repo -->
<artifactId>db2jcc4</artifactId>
<version>4.19.49</version>
</dependency>
DB connection properties:
spring.jpa.hibernate.ddl-auto=validate
spring.datasource.driver-class-name=com.ibm.db2.jcc.DB2Driver
spring.jpa.hibernate.dialect=org.hibernate.dialect.DB2Dialect
spring.jpa.hibernate.synonyms=true
spring.jpa.show-sql=true
spring.db2.datasource.url=jdbc:db2://HOSTNAME:PORT/DBNAME
spring.db2.datasource.username=somename
spring.db2.datasource.password=password
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery=SELECT 1
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
DB config code in spring boot:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "db2EntityManagerFactory", transactionManagerRef = "db2TransactionManager", basePackages = {
"com.example.db.repositories" })
public class DB2Config {
private Logger log = LogManager.getLogger(DB2Config.class);
#Value("${spring.datasource.driver-class-name}")
String driverClassName;
#Value("${spring.db2.datasource.url}")
String dataSourceUrl;
#Value("${spring.db2.datasource.username}")
String username;
#Value("${spring.db2.datasource.password}")
String passkey;
#Value("${spring.jpa.hibernate.ddl-auto}")
String hbm2ddl;
#Value("${spring.jpa.hibernate.dialect}")
String dialect;
#Bean
public DataSource db2DataSource() {
log.info("Loading db2 datasource");
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(dataSourceUrl);
dataSource.setUsername(username);
dataSource.setPassword(passkey);
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean db2EntityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(db2DataSource());
em.setPackagesToScan("com.example.db");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
final HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", hbm2ddl);
properties.put("hibernate.dialect", dialect);
em.setJpaPropertyMap(properties);
em.setPersistenceUnitName("db2");
return em;
}
#Bean
public PlatformTransactionManager db2TransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(db2EntityManagerFactory().getObject());
return transactionManager;
}
}

Per comment thread, when working with Db2, always be aware that the target platform (Z/OS, i-series , Linux/Unix/Windows) determines the SQL dialect , along with many other things. The platform determines the SQL dialect.
In your case, as you are working with Db2 for Z/OS, it was necessary to use the DB2390Dialect with your toolchain so that the correct catalog objects get referenced on the target database. Specifically SYSIBM is the schema for Db2-for-Z/OS catalog objects, while SYSCAT is the schema used for Linux/Unix/Windows.

Related

Spring boot Hibernate error "Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set" when working with multiple data sources

I am building a Springboot application that needs to talk to 2 different databases (DB2 and Oracle).
Spring-boot-starter-parent version 2.6.6
hibernate version 5.6.7.Final
I first added DB2 support and that was working fine until I added oracle related settings in application.properties file below.
Adding oracle related settings causes following error:
org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
Below are the databases and hibernate related settings from my application.properties:
# ==============================
# = DB2
db2.datasource.jdbc-url=jdbc:db2://SERVER1:PORT/DATABASE-1:currentSchema=SCHEMA;
db2.datasource.username=USER1
db2.datasource.password=PASSWORD1
db2.datasource.driver-class-name=com.ibm.db2.jcc.DB2Driver
db2.jpa.properties.hibernate.dialect=org.hibernate.dialect.DB2390Dialect
# ==============================
# = ORACLE
oracle.datasource.jdbc-url=jdbc:oracle:thin:#SERVER2:PORT/DATABASE-2
oracle.datasource.username=USER2
oracle.datasource.password=PASSWORD2
oracle.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
# ==============================
# = JPA / HIBERNATE
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
My pom.xml contains dependencies for oracle and DB2 amongs other required dependencies:
...
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>jcc</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<scope>runtime</scope>
</dependency>
...
I have placed my entities, repositories, and data source configurations into different packages as I read is required in this article https://www.javadevjournal.com/spring-boot/multiple-data-sources-with-spring-boot/. My package structure looks like:
project
- dataconfig
- db2
- config
- entity
- repository
- oracle
- config
- entity
- repository
I also added some entities and repositories and my configuration classes.
Here is my DB2Configuration class:
package project.dataconfig.db2.config;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "db2EntityManagerFactory",
transactionManagerRef = "db2TransactionManager",
basePackages = {
"project.dataconfig.db2.repository"
}
)
public class Db2Configuration {
#Primary
#Bean(name = "db2DataSource")
#ConfigurationProperties(prefix = "db2.datasource")
public DataSource db2DataSource() {
return DataSourceBuilder.create().build();
}
#Primary
#Bean(name = "db2EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder
, #Qualifier("db2DataSource") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("project.dataconfig.db2.entity")
.persistenceUnit("db2persistanceunit")
.build();
}
#Primary
#Bean(name = "db2TransactionManager")
public PlatformTransactionManager db2TransactionManager(
#Qualifier("db2EntityManagerFactory") EntityManagerFactory db2EntityManagerFactory) {
return new JpaTransactionManager(db2EntityManagerFactory);
}
}
Here is my OracleConfiguration class:
package project.dataconfig.oracle.config;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "oracleEntityManagerFactory",
transactionManagerRef = "oracleTransactionManager",
basePackages = {
"project.dataconfig.oracle.repository"
}
)
public class OracleConfiguration {
#Bean(name = "oracleDataSource")
#ConfigurationProperties(prefix = "oracle.datasource")
public DataSource oracleDataSource() {
return DataSourceBuilder.create().build();
}
#Bean(name = "oracleEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder
, #Qualifier("oracleDataSource") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("project.dataconfig.oracle.entity")
.persistenceUnit("oraclepersistanceunit")
.build();
}
#Bean(name = "oracleTransactionManager")
public PlatformTransactionManager oracleTransactionManager(
#Qualifier("oracleEntityManagerFactory") EntityManagerFactory oracleEntityManagerFactory) {
return new JpaTransactionManager(oracleEntityManagerFactory);
}
}
Before I added oracle related settings in application.properties file, my application worked just find with only DB2 settings as described above.
Once I added oracle related settings and configuration, I started getting this error:
org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
Based on the error, I think the problem is caused by my settings for Hibernate dialect in application.properties file. I think it is caused by one of the two settings
...
db2.jpa.properties.hibernate.dialect=org.hibernate.dialect.DB2390Dialect
...
oracle.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
How do I resolve this issue?
I figure it out.
Modify method entityManagerFactory for both Db2Configuration and OracleConfiguration to supply them with the information about hibernate dialect:
for DB2
#Primary
#Bean(name = "db2EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder
, #Qualifier("db2DataSource") DataSource dataSource) {
final HashMap<String, Object> hibernateProperties = new HashMap<String, Object>();
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.DB2390Dialect");
return builder
.dataSource(dataSource)
.packages("project.dataconfig.db2.entity")
.properties(hibernateProperties)
.persistenceUnit("db2persistanceunit")
.build();
}
for Oracle
#Bean(name = "oracleEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder
, #Qualifier("oracleDataSource") DataSource dataSource) {
final HashMap<String, Object> hibernateProperties = new HashMap<String, Object>();
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
return builder
.dataSource(dataSource)
.packages("project.dataconfig.oracle.entity")
.properties(hibernateProperties)
.persistenceUnit("oraclepersistanceunit")
.build();
}
After this, my console shows when running app, indicating all is good:
HHH000400: Using dialect: org.hibernate.dialect.DB2390Dialect
Initialized JPA EntityManagerFactory for persistence unit 'db2persistanceunit'
HHH000204: Processing PersistenceUnitInfo [name: oraclepersistanceunit]
HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
Initialized JPA EntityManagerFactory for persistence unit 'oraclepersistanceunit'
My actuator /health endpoint also sees both databases as up and running.

How can i connect to 2 different Schemas on one datasource in springboot

I am trying to extract data from multiple databases in different servers. This has been successful after configuring different Data sources as shown in my code however i cannot see to configure 2 different Data sources on the same connection.
I have tried to create 2 beans within the config file but i would still need to set the Data source.
#Configuration
#EnableJpaRepositories(basePackages = {"balances.Repository.World"},
entityManagerFactoryRef = "ASourceEntityManager",transactionManagerRef = "ASourceTransactionManager")
#EnableTransactionManagement
public class World{
#Autowired
private Environment env;
#Bean
public LocalContainerEntityManagerFactoryBean ASourceEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(ASourceDatasource());
em.setPackagesToScan(new String("balances.Repository.World"));
em.setPersistenceUnitName("ASourceEntityManager");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.dialect",env.getProperty("app.datasource.ASource.hibernate.dialect"));
properties.put("hibernate.show-sql",env.getProperty("app.datasource.ASource.show-sql"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
#ConfigurationProperties(prefix = "app.datasource.ASource")
public DataSource ASourceDatasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("app.datasource.ASource.driverClassName"));
dataSource.setUrl(env.getProperty("app.datasource.ASource.url"));
dataSource.setUsername(env.getProperty("app.datasource.ASource.username"));
dataSource.setPassword(env.getProperty("app.datasource.ASource.password"));
return dataSource;
}
#ConfigurationProperties(prefix = "app.datasource.ASourceB")
public DataSource ASourceDatasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("app.datasource.ASourceB.driverClassName"));
dataSource.setUrl(env.getProperty("app.datasource.ASourceB.url"));
dataSource.setUsername(env.getProperty("app.datasource.ASourceB.username"));
dataSource.setPassword(env.getProperty("app.datasource.ASourceB.password"));
return dataSource;
}
#Bean
public PlatformTransactionManager ASourceTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
ASourceEntityManager().getObject());
return transactionManager;
}
After some thought i have come up with a workaround that might be a bit hacky but gets the job done.
Instead of declaring a new database connection for the second schema in my app.properties i have used one connection. I placed all my entities in one model package and used a native query to access the other schema. In the native query i would then specify the schema eg:
select * from DATABASE1.Id;
This solution does not scale well as it would create a lot of work when dealing with a large number of entities so if there is a way of specifying the schema in the repository that would also help.
I tried using the entity attributes to define my schema but jpa seems to be ignoring it and prefixing the table with the wrong schema for example if
i annotate my class with the following
#Table(name = "Payment", schema = "DATABASE1", catalog = "")
The resulting query would be "select * from DATABASE2.Payment" instead of
select * from DATABASE1.Payment

Spring Boot - Use underscored table and column names for custom data source

I am trying to configure two data sources for a Spring Boot project. Here is my configuration file for primary data source.
#PropertySource({"classpath:application-local.properties"})
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "primaryEntityManager",
basePackages = {"portal.api.repository"}
)
public class PrimaryDbConfig {
#Autowired
private Environment env;
#Bean
#Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(primaryDataSource());
em.setPackagesToScan(
new String[]{"portal.api.model"});
HibernateJpaVendorAdapter vendorAdapter
= new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("app.datasource.spring.jpa.hibernate.ddl"));
properties.put("hibernate.dialect",
env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Primary
#Bean
public DataSource primaryDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("app.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("app.datasource.url"));
dataSource.setUsername(env.getProperty("app.datasource.username"));
dataSource.setPassword(env.getProperty("app.datasource.password"));
return dataSource;
}
#Primary
#Bean
public PlatformTransactionManager userTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
primaryEntityManager().getObject());
return transactionManager;
}
}
The tables are generated but their names and column names are in camel case. However I would like to have the underscore names which spring boot has by default. For example ApiKey entity would be changed to table name api_key.
How do I configure Spring Boot to use the underscored naming strategy?
I think if you use #Column(name = "api_key") in your instance variable for your domain model it'll work.
e.g.
#Column(name = "api_key")
private String apiKey;
Reference from Official doc
By default, Spring Boot configures the physical naming strategy with
SpringPhysicalNamingStrategy. This implementation provides the same
table structure as Hibernate 4: all dots are replaced by underscores
and camel casing is replaced by underscores as well.
You can set the following property in application.yml to tell springboot which naming strategy to use:
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
Similar post for reference:
java.sql.SQLSyntaxErrorException: Unknown column .JPA Entity Issue?

Spring Boot Dual data configuration, unable to reconnect after connection lost

I am working on application written in spring Boot 1.5.3. I have two data source which are configured as below.
Main connection
spring.datasource.driverClassName = org.postgresql.Driver
spring.datasource.url = jdbc:postgresql://xxx.xxx.xxx.xx:5432/mydb
spring.datasource.username = xxxx
spring.datasource.password = xxxx
spring.jpa.properties.hibernate.default_schema=test
# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.tomcat.max-wait=10000
# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=150
spring.datasource.tomcat.max-idle=30
spring.datasource.tomcat.min-idle=2
spring.datasource.tomcat.initial-size=3
# Validate the connection before borrowing it from the pool.
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.test-on-connect=true
spring.datasource.time-between-eviction-runs-millis=60000
#spring.datasource.tomcat.validation-query-timeout=1000
spring.datasource.tomcat.validation-query=SELECT 1
spring.datasource.tomcat.validation-interval=1000
spring.datasource.tomcat.remove-abandoned=true
spring.datasource.tomcat.remove-abandoned-timeout=55
spring.datasource.tomcat.test-while-idle=true
spring.datasource.tomcat.min-evictable-idle-time-millis = 55000
spring.datasource.tomcat.time-between-eviction-runs-millis = 34000
Second Connection
spring.rdatasource.driverClassName = org.postgresql.Driver
spring.rdatasource.url = jdbc:postgresql://xxx.xxx.xxx.xx:5432/mydb1
spring.rdatasource.username = xxxx
spring.rdatasource.password = xxxx
spring.jpa.properties.hibernate.default_schema=test
# Number of ms to wait before throwing an exception if no connection is available.
spring.rdatasource.tomcat.max-wait=10000
# Maximum number of active connections that can be allocated from this pool at the same time.
spring.rdatasource.tomcat.max-active=150
spring.rdatasource.tomcat.max-idle=30
spring.rdatasource.tomcat.min-idle=2
spring.rdatasource.tomcat.initial-size=3
# Validate the connection before borrowing it from the pool.
spring.rdatasource.tomcat.test-on-borrow=true
spring.rdatasource.tomcat.test-on-connect=true
spring.rdatasource.time-between-eviction-runs-millis=60000
#spring.rdatasource.tomcat.validation-query-timeout=1000
spring.rdatasource.tomcat.validation-query=SELECT 1
spring.rdatasource.tomcat.validation-interval=1000
spring.rdatasource.tomcat.remove-abandoned=true
spring.rdatasource.tomcat.remove-abandoned-timeout=55
spring.rdatasource.tomcat.test-while-idle=true
spring.rdatasource.tomcat.min-evictable-idle-time-millis = 55000
spring.rdatasource.tomcat.time-between-eviction-runs-millis = 34000
I am working in in VPN environment. When I run application, application is working fine. But the issue starts when I disconnect the VPN and reconnect the VPN.again, my application won't reconnect to data source again. Instead I always getting exception.
But working single database when leave connection handling to spring itself and I do not perform any database configuration.
Update
#Configuration
#PropertySource({ "classpath:application.properties" })
#EnableJpaRepositories(
basePackages = {"com.services.persistence"},
entityManagerFactoryRef = "entityManager",
transactionManagerRef = "transactionManager"
)
#ComponentScan("com.services.persistence")
#EnableTransactionManagement
public class DBConfig {
#Autowired private Environment env;
#Bean
#Primary
public LocalContainerEntityManagerFactoryBean entityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(userDataSource());
em.setPackagesToScan(
new String[] { "com.services.persistence", "com.services.persistence.pojo" });
HibernateJpaVendorAdapter vendorAdapter
= new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
// properties.put("hibernate.hbm2ddl.auto",
// env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("spring.jpa.database-platform"));
properties.put("hibernate.current_session_context_class",
env.getProperty("spring.jpa.properties.hibernate.current_session_context_class"));
em.setJpaPropertyMap(properties);
return em;
}
#Primary
#Bean
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource userDataSource() {
return DataSourceBuilder
.create()
.build();
}
#Primary
#Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
entityManager().getObject());
return transactionManager;
}
#Bean(name = "sessionFactory")
public SessionFactory getSessionFactory() {
SessionFactory sessionFactory = transactionManager().getEntityManagerFactory().unwrap(SessionFactory.class);
if (sessionFactory == null) {
throw new NullPointerException("factory is not a hibernate factory");
} else {
System.out.println(
"==================================== Transaction Enabled ========================================");
return sessionFactory;
}
}
I have also configured spring.rdatasource and it is same as above file, except it is not set as primary and other further details like pojo, transactionmanager etc.

Spring Boot + Camel JPA with multiple Datasources

I need to create a Camel route that polls a DB, transforms the retrieved data and then inserts the new entities into another DB. I need help with the configuration.
These are the jpa endpoints:
from("jpa://" + Entity1.class.getName()
+ "?"
+ "persistenceUnit=entity1PU&"
+ "consumer.namedQuery=query1&"
+ "consumeDelete=false"
)
//various operations...
.to("direct:route2");
from("direct:route2")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
//processing...
}
})
.to("jpa://" + Entity2.class.getName()
+ "?"
+ "persistenceUnit=entity2PU&"
+ "entityType=java.util.ArrayList&"
+ "usePersist=true&"
+ "flushOnSend=true");
I'd like to configure the persistence units by code and annotations, instead of using persistence.xml; these are the relative classes. This is the first:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
basePackages = "com.foo.entity1.repo",
entityManagerFactoryRef = "entity1EntityManagerFactory",
transactionManagerRef = "entity1TransactionManager"
)
public class Entity1PersistenceConfig {
#Autowired
#Qualifier("datasource1")
private DataSource dataSource;
#Primary
public DataSource dataSource() {
return this.dataSource;
}
#Primary
#Bean(name="entity1EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.foo.entity1.domain");
factory.setDataSource(this.dataSource());
factory.setPersistenceProviderClass(HibernatePersistenceProvider.class);
factory.setPersistenceUnitName("entity1PU");
Properties hibernateProps = setJpaHibernateCommonProperties();
hibernateProps.setProperty("hibernate.dialect", environment.getProperty("spring.jpa.properties.hibernate.oracle.dialect"));
factory.setJpaProperties(hibernateProps);
return factory;
}
#Primary
#Bean(name="entity1TransactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return jpaTransactionManager;
}
}
and the second one:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
basePackages = "com.foo.entity2.repo",
entityManagerFactoryRef = "entity2EntityManagerFactory",
transactionManagerRef = "entity2TransactionManager"
)
public class Entity2PersistenceConfig {
#Autowired
#Qualifier("datasource2")
private DataSource dataSource;
public DataSource dataSource() {
return this.dataSource;
}
#Bean(name="entity2EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.foo.entity2.domain");
factory.setDataSource(this.dataSource());
factory.setPersistenceProviderClass(HibernatePersistenceProvider.class);
factory.setPersistenceUnitName("entity2PU");
Properties hibernateProps = setJpaHibernateCommonProperties();
hibernateProps.setProperty("hibernate.dialect", environment.getProperty("spring.jpa.properties.hibernate.mysql.dialect"));
factory.setJpaProperties(hibernateProps);
return factory;
}
#Bean(name="entity2TransactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return jpaTransactionManager;
}
}
Entities and repositories are in the correct packages; also, the configuration of the databases is correctly done in a specific class, and are correctly injected.
When I try to run the project, I get the following:
2018-05-30 11:38:36.481 INFO 1056 --- [main] o.h.j.b.internal.PersistenceXmlParser: HHH000318: Could not find any META-INF/persistence.xml file in the classpath
and
javax.persistence.PersistenceException: No Persistence provider for EntityManager named entity1PU
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61) ~[hibernate-jpa-2.1-api-1.0.0.Final.jar:1.0.0.Final]
at org.springframework.orm.jpa.LocalEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalEntityManagerFactoryBean.java:96) ~[spring-orm-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:384) ~[spring-orm-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371) ~[spring-orm-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.apache.camel.component.jpa.JpaEndpoint.createEntityManagerFactory(JpaEndpoint.java:552) ~[camel-jpa-2.21.1.jar:2.21.1]
at org.apache.camel.component.jpa.JpaEndpoint.getEntityManagerFactory(JpaEndpoint.java:250) ~[camel-jpa-2.21.1.jar:2.21.1]
at org.apache.camel.component.jpa.JpaEndpoint.validate(JpaEndpoint.java:545) ~[camel-jpa-2.21.1.jar:2.21.1]
at org.apache.camel.component.jpa.JpaEndpoint.createConsumer(JpaEndpoint.java:165) ~[camel-jpa-2.21.1.jar:2.21.1]
at org.apache.camel.impl.EventDrivenConsumerRoute.addServices(EventDrivenConsumerRoute.java:69) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultRoute.onStartingServices(DefaultRoute.java:103) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.RouteService.doWarmUp(RouteService.java:172) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.RouteService.warmUp(RouteService.java:145) ~[camel-core-2.21.1.jar:2.21.1]
Why is it looking for a persistence.xml file instead of using annotations? I'm using Spring Boot 1.5.13.RELEASE with Camel 2.21.1.
Basically to make it work I had to abandon using annotations and create an equivalent persistence.xml file, because Apache Camel was looking for configuration only in it.
As soon as I could upgrade to Spring Boot 2 (because Apache Camel got updated and started to support it), I managed to make configuration by annotations work and dropped the persistence.xml file.

Resources