The two database have some same name tables, for example the table with name summary, when I create repository, an error occurred! what should i do? the error is:
#Autowired
SummaryDao summaryDao;
RROR o.s.b.d.LoggingFailureAnalysisReporter -
*************************** APPLICATION FAILED TO START
Description:
Field summaryDao in
com.tc.spider.schedule.logic.combination.CombinationDailyNetLogic
required a bean of type 'com.tc.spider.dao.user.SummaryDao' that could
not be found.
Action:
Consider defining a bean of type 'com.tc.spider.dao.user.SummaryDao'
in your configuration.
the datasource config file is below:
`
package com.tc.spider.config.db;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
#Configuration
public class DataSourceConfig {
#Bean(name = "primaryDataSource")
#Qualifier("primaryDataSource")
#Primary // 该数据源为主数据源
#ConfigurationProperties(prefix = "spring.datasource.tct")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
#Bean(name = "secondaryDataSource")
#Qualifier("secondaryDataSource")
#ConfigurationProperties(prefix = "spring.datasource.market")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#Primary // jdbc默认的主数据源
public JdbcTemplate primaryJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
#Bean(name = "marketJdbcTemplate")
public JdbcTemplate marketJdbcTemplate(#Qualifier("secondaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
`
primary datasource
`
package com.tc.spider.config.db;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary", // 配置连接工厂 entityManagerFactory
transactionManagerRef = "transactionManagerPrimary", // 配置 事物管理器 transactionManager
basePackages = {"com.tc.spider.dao.user"}) // 设置Repository所在位置
public class PrimaryConfig {
#Autowired
#Qualifier("primaryDataSource")
private DataSource primaryDataSource;
#Bean(name = "entityManagerPrimary")
#Primary
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
#Bean(name = "entityManagerFactoryPrimary")
#Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
// 设置数据源
.dataSource(primaryDataSource)
// 设置数据源属性
.properties(getVendorProperties(primaryDataSource))
// 设置实体类所在位置.扫描所有带有 #Entity 注解的类
.packages("com.tc.spider.model.user")
// Spring会将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之后,
// Repository就能用它来创建 EntityManager 了,然后 EntityManager 就可以针对数据库执行操作
.persistenceUnit("primaryPersistenceUnit")
.build();
}
#Autowired
private JpaProperties jpaProperties;
private Map getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}
/**
* 配置事物管理器
*
* #param builder
* #return
*/
#Bean(name = "transactionManagerPrimary")
#Primary
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
`
SecondaryConfig.java this is the second datasource config
`
package com.tc.spider.config.db;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecondary", // 配置连接工厂 entityManagerFactory
transactionManagerRef = "transactionManagerSecondary", // 配置 事物管理器 transactionManager
basePackages = {"com.tc.spider.dao.market"}) // 设置Repository所在位置
public class SecondaryConfig {
#Autowired
#Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
#Bean(name = "entityManagerSecondary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
#Bean(name = "entityManagerFactorySecondary")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) {
return builder
// 设置数据源
.dataSource(secondaryDataSource)
// 设置数据源属性
.properties(getVendorProperties(secondaryDataSource))
// 设置实体类所在位置.扫描所有带有 #Entity 注解的类
.packages("com.tc.spider.model.market") //设置实体类所在位置
// Spring会将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之后,
// Repository就能用它来创建 EntityManager 了,然后 EntityManager 就可以针对数据库执行操作
.persistenceUnit("secondaryPersistenceUnit")
.build();
}
#Autowired
private JpaProperties jpaProperties;
private Map getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}
/**
* 配置事物管理器
*
* #param builder
* #return
*/
#Bean(name = "transactionManagerSecondary")
public PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
`
Related
I am implementing a read-only db source but although there is no conflicting bean, it got bean error.
How can I fix the below issue ?
The bean 'routingDataSource', defined in class path resource [io/api/masterSlave/datasources/DataSourcesConfiguration.class], could not be registered. A bean with that name has already been defined in file [/Users/neslihan.bozer/Codes/api-backend/target/classes/io/api/masterSlave/routing/RoutingDataSource.class] and overriding is disabled.
package io.api.masterSlave.datasources;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import io.api.masterSlave.properties.Properties;
import io.api.masterSlave.routing.RoutingDataSource;
#Configuration
#ComponentScan
#EnableJpaRepositories("io.api.persistence.repository")
public class DataSourcesConfiguration {
#Autowired
private Properties props;
#Bean(name = "masterDataSource1")
#Primary
public DataSource masterDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(props.getProperty("spring.datasource.master.driver-class-name"));
dataSource.setDefaultAutoCommit(false);
dataSource.setUsername(props.getProperty("spring.datasource.master.username"));
dataSource.setPassword(props.getProperty("spring.datasource.master.password"));
dataSource.setUrl(props.getProperty("spring.datasource.master.url"));
return dataSource;
}
#Bean
public RoutingDataSource routingDataSource() {
RoutingDataSource dataSource = new RoutingDataSource();
dataSource.setDefaultTargetDataSource(masterDataSource());
Map<Object, Object> targets = new HashMap<>();
targets.put(DataSourceType.MASTER, masterDataSource());
targets.put(DataSourceType.SLAVE, slaveDataSource());
dataSource.setTargetDataSources(targets);
dataSource.afterPropertiesSet();
return dataSource;
}
#Bean(name = "slaveDataSource2")
public DataSource slaveDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(props.getProperty("spring.datasource.slave.driver-class-name"));
dataSource.setDefaultAutoCommit(false);
dataSource.setUsername(props.getProperty("spring.datasource.slave.username"));
dataSource.setPassword(props.getProperty("spring.datasource.slave.password"));
dataSource.setUrl(props.getProperty("spring.datasource.slave.url"));
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(masterDataSource());
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(Boolean.parseBoolean(props.getProperty("spring.jpa.generate-ddl")));
Map<String, String> additionalProperties = new HashMap<>();
additionalProperties.put("hibernate.dialect", props.getProperty("spring.jpa.dialect"));
LocalContainerEntityManagerFactoryBean factory = builder.dataSource(routingDataSource())
.packages("io.api.persistence.entity").persistenceUnit("routingEntityMF").properties(additionalProperties)
.build();
factory.setJpaVendorAdapter(vendorAdapter);
factory.afterPropertiesSet();
return factory;
}
}
RoutingDataSource.java
package io.api.masterSlave.routing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Service;
#Service
public class RoutingDataSource extends AbstractRoutingDataSource {
#Autowired
private DbHolder dbHolder;
#Override
protected Object determineCurrentLookupKey() {
return dbHolder.getDbType();
}
}
I have to connect to multiple data sources at runtime in a spring boot application with amazon RDS deployed MySQL and MariaDB instances respectively. For now, both are MariaDB instances residing separately. I have used the usual spring boot configurations like here
Multiple data source and schema creation in Spring Boot
I am facing a problem here and that is I am not able to connect to the secondary data source where as I am able to connect to the primary data source.
Here are some code snippets.
Also, I want to know any mechanism to fall back to other database instances of the same schemas at runtime if the original ones are down without affecting the application or restarting it. I have no idea about that.
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.HashMap;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "a.b.c.d.e",
entityManagerFactoryRef = "aEntityManagerFactory",
transactionManagerRef = "aTransactionManager"
)
public class aConfiguration {
#Bean
#Primary
#ConfigurationProperties("app.datasource.a")
public DataSourceProperties aDataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#Primary
#ConfigurationProperties("app.datasource.a.configuration")
public DataSource aDataSource() {
return aDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
#Bean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder() {
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), new HashMap<>(), null);
}
#Primary
#Bean(name = "aEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean aEntityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(aDataSource())
.packages(SomeQualifiedEntity.class)
.build();
}
#Primary
#Bean
public PlatformTransactionManager aTransactionManager(
final #Qualifier("aEntityManagerFactory") LocalContainerEntityManagerFactoryBean aEntityManagerFactory) {
return new JpaTransactionManager(aEntityManagerFactory.getObject());
}
}
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.HashMap;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "u.v.w.x.y",
entityManagerFactoryRef = "bEntityManagerFactory",
transactionManagerRef = "bTransactionManager"
)
public class aConfiguration {
#Bean
#Primary
#ConfigurationProperties("app.datasource.b")
public DataSourceProperties bDataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#Primary
#ConfigurationProperties("app.datasource.b.configuration")
public DataSource bDataSource() {
return bDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
#Bean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder() {
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), new HashMap<>(), null);
}
#Primary
#Bean(name = "bEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean bEntityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(bDataSource())
.packages(SomeQualifiedEntity.class)
.build();
}
#Primary
#Bean
public PlatformTransactionManager bTransactionManager(
final #Qualifier("bEntityManagerFactory") LocalContainerEntityManagerFactoryBean bEntityManagerFactory) {
return new JpaTransactionManager(aEntityManagerFactory.getObject());
}
}
app.datasource.a.url=
app.datasource.a.username=
app.datasource.a.password=
app.datasource.a.driverClassName=org.mariadb.jdbc.Driver
app.datasource.b.url=
app.datasource.b.username=
app.datasource.b.password=
app.datasource.b.driverClassName=org.mariadb.jdbc.Driver
I wish I could provide the entities and the repositories, but I can't. Sorry for that.
I configured my database / datasource in spring in the application.properties file. Although I just had one DB, I tried it with multiple out of curiosity and it worked. So maybe try it there? The format is as such:
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.data.jpa.repositories.bootstrap-mode=default
Is it possible to cross join between two different database tables (2 DataSources) in Spring Boot using JPA? If so, how would you configure this configuration? In the application.properties, 4 databases are already being defined and 4 files have been created that represent the configurations of the DataSources. The scenario is that there is a DataSource 1 table that has a FOREIGN KEY with a DataSource 2 table, but when the application is raised an Exception is generated:
#OneToOne or #ManyToOne on com.smart4.bdcentral.domain.files.IndividuoFoto .persons references an unknown entity: com.smart4.bdcentral.domain.main.IndividuoPessoa
DataSource 1
package com.smart4.configBases;
import java.util.HashMap;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import com.google.common.base.Preconditions;
#Configuration
#PropertySource({ "classpath:application.properties" })
#EnableJpaRepositories(basePackages = {"com.smart4.bdcentral.repository.main"},
entityManagerFactoryRef = "bdCentralMainEntityManager",
transactionManagerRef = "bdCentralMainTransactionManager")
public class BdCentralMain {
#Autowired
private Environment env;
public BdCentralMain() {
super();
}
#Bean
public LocalContainerEntityManagerFactoryBean bdCentralMainEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(bdCentralMainDataSource());
em.setPackagesToScan(new String[] { "com.smart4.bdcentral.domain.main" });
em.setPersistenceUnitName("bdcentralmain");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.MYSQL);
vendorAdapter.setShowSql(false);
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
em.setJpaVendorAdapter(vendorAdapter);
final HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("bdcentralmain.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("bdcentralmain.hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
public DataSource bdCentralMainDataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource
.setDriverClassName(Preconditions.checkNotNull(env.getProperty("bdcentralmain.jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("bdcentralmain.jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("bdcentralmain.jdbc.user")));
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("bdcentralmain.jdbc.pass")));
return dataSource;
}
#Bean
public PlatformTransactionManager bdCentralMainTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(bdCentralMainEntityManager().getObject());
return transactionManager;
}
}
DataSource 2
package com.smart4.configBases;
import java.util.HashMap;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import com.google.common.base.Preconditions;
#Configuration
#PropertySource({ "classpath:application.properties" })
#EnableJpaRepositories(basePackages = {"com.smart4.bdcentral.repository.files"},
entityManagerFactoryRef = "bdCentralFilesEntityManager",
transactionManagerRef = "bdCentralFilesTransactionManager")
public class BdCentralFiles {
#Autowired
private Environment env;
public BdCentralFiles() {
super();
}
#Bean
public LocalContainerEntityManagerFactoryBean bdCentralFilesEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(bdCentralFilesDataSource());
em.setPackagesToScan(new String[] { "com.smart4.bdcentral.domain.files" });
em.setPersistenceUnitName("bdcentralfiles");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.MYSQL);
vendorAdapter.setShowSql(false);
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
em.setJpaVendorAdapter(vendorAdapter);
final HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("bdcentralfiles.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("bdcentralfiles.hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
public DataSource bdCentralFilesDataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource
.setDriverClassName(Preconditions.checkNotNull(env.getProperty("bdcentralfiles.jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("bdcentralfiles.jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("bdcentralfiles.jdbc.user")));
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("bdcentralfiles.jdbc.pass")));
return dataSource;
}
#Bean
public PlatformTransactionManager bdCentralFilesTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(bdCentralFilesEntityManager().getObject());
return transactionManager;
}
}
not much to say with just the datasources, check the annotation configuration and make sure your objects are #Entity annotated. It doesn't sound like you actually want a "cross join", also you're looking at Hibernate, I kept reading Spring Boot JPA as spring "Data" JPA and was getting confused as to why it wasn't data jpa lol.
For some reason, my db tables are not being created according to the entity model in the codebase. I am looking for the codebase to lead, and create the tables in the db, every time the server starts.
I have this in src/main/resources/application.properties
################### DataSource Configuration ##########################
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:~/test
jdbc.username=sa
jdbc.password=
################### spring config ####################################
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
################### Hibernate Configuration ##########################
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
I bet some of that is redundant or maybe even contradictory. I doubt I need spring.jpa and hibernate, since they conflict. My current preference is to use Hibernate for ORM.
I also have:
package huru.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Trivial JPA entity for vertx-spring demo
*/
#Entity
#Table(name="HURU_USER")
public class User {
#Id
#Column(name="ID")
private Integer productId;
#Column
private String description;
public Integer getProductId() {
return this.productId;
}
public String getDescription() {
return this.description;
}
}
and I have this:
package huru.repository;
import huru.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Spring Data JPA repository to connect our service bean to data
*/
public interface UserRepository extends JpaRepository<User, Integer> {
}
and here is the SpringConfiguration
package huru.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.Properties;
/**
* Simple Java Spring configuration to be used for the Spring example application. This configuration is mainly
* composed of a database configuration and initial population via the script "products.sql" of the database for
* querying by our Spring service bean.
* <p>
* The Spring service bean and repository are scanned for via #EnableJpaRepositories and #ComponentScan annotations
*/
#Configuration
#EnableJpaRepositories(basePackages = {"huru.repository"})
#PropertySource(value = {"classpath:application.properties"})
#ComponentScan("huru.service")
public class SpringConfiguration {
#Autowired
private Environment env;
#Bean
#Autowired
public DataSource dataSource(DatabasePopulator populator) {
final DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(env.getProperty("jdbc.driverClassName"));
ds.setUrl(env.getProperty("jdbc.url"));
ds.setUsername(env.getProperty("jdbc.username"));
ds.setPassword(env.getProperty("jdbc.password"));
DatabasePopulatorUtils.execute(populator, ds);
return ds;
}
#Bean
#Autowired
public LocalContainerEntityManagerFactoryBean entityManagerFactory(final DataSource dataSource) {
final LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource);
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(Boolean.TRUE);
vendorAdapter.setShowSql(Boolean.TRUE);
factory.setDataSource(dataSource);
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("huru.entity");
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
jpaProperties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
factory.setJpaProperties(jpaProperties);
return factory;
}
#Bean
#Autowired
public PlatformTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory.getObject());
}
#Bean
public DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.setContinueOnError(false);
populator.addScript(new ClassPathResource("users.sql"));
return populator;
}
}
package huru.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.Properties;
/**
* Simple Java Spring configuration to be used for the Spring example application. This configuration is mainly
* composed of a database configuration and initial population via the script "products.sql" of the database for
* querying by our Spring service bean.
* <p>
* The Spring service bean and repository are scanned for via #EnableJpaRepositories and #ComponentScan annotations
*/
#Configuration
#EnableJpaRepositories(basePackages = {"huru.repository"})
#PropertySource(value = {"classpath:application.properties"})
#ComponentScan("huru.service")
public class SpringConfiguration {
#Autowired
private Environment env;
#Bean
#Autowired
public DataSource dataSource(DatabasePopulator populator) {
final DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(env.getProperty("jdbc.driverClassName"));
ds.setUrl(env.getProperty("jdbc.url"));
ds.setUsername(env.getProperty("jdbc.username"));
ds.setPassword(env.getProperty("jdbc.password"));
DatabasePopulatorUtils.execute(populator, ds);
return ds;
}
#Bean
#Autowired
public LocalContainerEntityManagerFactoryBean entityManagerFactory(final DataSource dataSource) {
final LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource);
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(Boolean.TRUE);
vendorAdapter.setShowSql(Boolean.TRUE);
factory.setDataSource(dataSource);
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("huru.entity");
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
jpaProperties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
factory.setJpaProperties(jpaProperties);
return factory;
}
#Bean
#Autowired
public PlatformTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory.getObject());
}
#Bean
public DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.setContinueOnError(false);
populator.addScript(new ClassPathResource("users.sql"));
return populator;
}
}
so yeah like I said, I am hoping to see a table called "USER" in the db, but it doesn't seem to be happening.
Yeah the datasource info in application.properties was wrong, should have looked like this instead:
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/oleg
jdbc.username=postgres
jdbc.password=postgres
I am trying to configure two EntityManagerFactory for one spring boot application. Each of those EntityManagerFactorys should work with different databases. Also would be great if one of them would be used as a default (e.g. when not explicit information was provided during on which one should be used).
Here is my code:
pkg/Application.java
package pkg;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).run(args);
}
}
pkg/PrimaryDbConfig.java
package pkg;
import org.h2.jdbcx.JdbcDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
#Configuration
public class PrimaryDbConfig {
public static final String DB = "primary";
#Bean
#Primary
public DataSource primaryDataSource() {
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:file:~\\db\\test;AUTO_SERVER=TRUE");
ds.setUser("sa");
ds.setPassword("sa");
return ds;
}
#Bean
#Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName(DB);
factoryBean.setDataSource(primaryDataSource());
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factoryBean.setPackagesToScan("pkg.entities");
return factoryBean;
}
#Bean
#Primary
public PlatformTransactionManager primaryTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(primaryEntityManagerFactoryBean().getObject());
return transactionManager;
}
}
pkg/SecondaryDbConfig.java
package pkg;
import org.h2.jdbcx.JdbcDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
#Configuration
public class SecondaryDbConfig {
public static final String DB = "secondary";
#Bean
public DataSource secondaryDataSource() {
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:file:~\\db\\test2;AUTO_SERVER=TRUE");
ds.setUser("sa");
ds.setPassword("sa");
return ds;
}
#Bean
public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName(DB);
factoryBean.setDataSource(secondaryDataSource());
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factoryBean.setPackagesToScan("pkg.entities");
return factoryBean;
}
#Bean
public PlatformTransactionManager secondaryTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(secondaryEntityManagerFactoryBean().getObject());
return transactionManager;
}
}
pkg/repositories/PrimaryRepository.java
package pkg.repositories;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import pkg.entities.SomeEntity;
import javax.persistence.EntityManager;
#Repository
#Transactional
public class PrimaryRepository {
private final EntityManager entityManager;
public PrimaryRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
public SomeEntity find(Integer id) {
return entityManager.find(SomeEntity.class, id);
}
}
pkg/repositories/SecondaryRepository.java
package pkg.repositories;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import pkg.entities.SomeEntity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Repository
#Transactional("secondaryTransactionManager")
public class SecondaryRepository {
#PersistenceContext(unitName = "secondary")
private final EntityManager entityManager;
public SecondaryRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
public SomeEntity find(Integer id) {
return entityManager.find(SomeEntity.class, id);
}
}
build.gradle
plugins {
id 'org.springframework.boot' version '1.5.7.RELEASE'
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile "com.h2database:h2:1.4.193"
compile "org.hibernate:hibernate-core:5.2.10.Final"
compile ("org.springframework.boot:spring-boot-starter-data-jpa:1.5.2.RELEASE") {
exclude module: 'tomcat-jdbc'
}
}
Running this app I am getting next error:
Description:
Parameter 0 of constructor in pkg.repositories.PrimaryRepository required a single bean, but 2 were found:
- org.springframework.orm.jpa.SharedEntityManagerCreator#0: defined by method 'createSharedEntityManager' in null
- org.springframework.orm.jpa.SharedEntityManagerCreator#1: defined by method 'createSharedEntityManager' in null