我想将Spring Boot配置为使用2个JNDI数据源。我尝试了以下配置:
application.properties
spring.production.datasource.jndi-name=java:/global/production_gateway
spring.production.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.production.datasource.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.production.datasource.jpa.show-sql = true
spring.production.datasource.jpa.hibernate.ddl-auto = update
spring.warehouse.datasource.jndi-name=java:/global/production_warehouse
spring.warehouse.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.warehouse.datasource.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.warehouse.datasource.jpa.show-sql = true
spring.warehouse.datasource.jpa.hibernate.ddl-auto = update
主数据库
@Configuration
@EnableJpaRepositories(
basePackages = "org.datalis.plugin.production.entity",
entityManagerFactoryRef = "productionEntityManagerFactory",
transactionManagerRef = "productionTransactionManager"
)
@EnableTransactionManagement
public class ContextProductionDatasource {
@Primary
@Bean(name = "productionDataSourceProperties")
@ConfigurationProperties(prefix="spring.production.datasource")
public JndiPropertyHolder productionDataSourceProperties() {
return new JndiPropertyHolder();
}
@Primary
@Bean(name = "productionDataSource")
@ConfigurationProperties(prefix="spring.production.datasource")
public DataSource productionDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource(productionDataSourceProperties().getJndiName());
return dataSource;
}
@Primary
@Bean(name = "productionEntityManager")
public EntityManager productionEntityManager(EntityManagerFactory emf) {
return emf.createEntityManager();
}
@Primary
@Bean(name = "productionEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean productionEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", "update");
return builder
.dataSource(productionDataSource())
.packages("org.datalis.plugin.production.entity")
.persistenceUnit("production")
.properties(properties)
.build();
}
@Primary
@Bean(name = "productionTransactionManager")
public PlatformTransactionManager productionTransactionManager(final EntityManagerFactory emf) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Primary
@Bean(name = "productionExceptionTranslation")
public PersistenceExceptionTranslationPostProcessor productionExceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private static class JndiPropertyHolder {
private String jndiName;
public String getJndiName() {
return jndiName;
}
public void setJndiName(String jndiName) {
this.jndiName = jndiName;
}
}
}
第二个数据源:
@Configuration
@EnableJpaRepositories(
basePackages = "org.datalis.plugin.warehouse.entity",
entityManagerFactoryRef = "warehouseEntityManagerFactory",
transactionManagerRef = "warehouseTransactionManager"
)
@EnableTransactionManagement
public class ContextWarehouseDatasource {
@Bean(name = "warehouseDataSourceProperties")
@ConfigurationProperties(prefix="spring.warehouse.datasource")
public JndiPropertyHolder warehouseDataSourceProperties() {
return new JndiPropertyHolder();
}
@Bean(name = "warehouseDataSource")
@ConfigurationProperties(prefix="spring.warehouse.datasource")
public DataSource warehouseDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource(warehouseDataSourceProperties().getJndiName());
return dataSource;
}
@Bean(name = "warehouseEntityManager")
public EntityManager warehouseEntityManager(EntityManagerFactory emf) {
return emf.createEntityManager();
}
@Bean(name = "warehouseEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean warehouseEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", "update");
return builder
.dataSource(warehouseDataSource())
.packages("org.datalis.plugin.warehouse.entity")
.persistenceUnit("warehouse")
.properties(properties)
.build();
}
@Bean(name = "warehouseTransactionManager")
public PlatformTransactionManager warehouseTransactionManager(final EntityManagerFactory emf) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean(name = "warehouseExceptionTranslation")
public PersistenceExceptionTranslationPostProcessor warehouseExceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private static class JndiPropertyHolder {
private String jndiName;
public String getJndiName() {
return jndiName;
}
public void setJndiName(String jndiName) {
this.jndiName = jndiName;
}
}
}
部署代码时出现异常:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
完整的错误堆栈:https:
//pastebin.com/bBZPZGfu
你知道我该怎么解决吗?
当我删除时:
@Primary
@Bean(name = "productionEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean productionEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", "update");
return builder
.dataSource(productionDataSource())
.packages("org.datalis.plugin.production.entity")
.persistenceUnit("production")
.properties(properties)
.build();
}
该软件包已正确部署。知道为什么吗?
主要问题是要有2个不同的实体管理器,它们可以访问不同的数据库。
因此,产生异常的原因是:Spring Data JPA尝试创建一组存储库,但不知道要使用哪个实体管理器工厂。默认情况下,Spring Data
JPA期望只使用一个实体管理器工厂bean(最好命名为)entityManagerFactory
,但是您没有这样的名字。
因此,您必须非常精确地进行配置:例如,您可以将代码组织为2个软件包:...warehouse.*
和app.production.*
,然后可以指定Spring
Data JPA:@EnableJpaRepositories(basePackages = "...warehouse.**", entityManagerFactoryRef = "warehouseEntityManagerFactory")
和供生产使用的精确配置@EnableJpaRepositories(basePackages = "...production.**", entityManagerFactoryRef = "productionEntityManagerFactory")
。
第二步是确保不执行默认的Data
JPA实例化:添加配置属性spring.data.jpa.repositories.enabled=false
将解决此问题。
并通过配置查看禁用任何其他类型@EnableJpaRepositories
或@EntityScan
以上定义的 精确配置 。
并且在创建过程中LocalContainerEntityManagerFactoryBean
不要使用注入EntityManagerFactoryBuilder
:死简单new LocalContainerEntityManagerFactoryBean()
将更好地工作。
最后但并非最不重要的一点是,它通常与应用程序有关:您必须考虑两阶段提交事务:您有2个数据源,可以在单个事务中访问这些数据源,但是每个数据源都由不同的事务管理器管理。
我创建了一个Spring Boot应用程序,并使用我想要执行的方法创建了一个类。将项目部署为war文件时,我从stacktrac中获取错误。我想从类TennisExecitor中运行该方法。 没有名为'entityManagerFactory'的bean可用 创建名为'(内部bean)#366583f9'的bean时出错:设置构造函数参数时无法解析对bean'entityManagerFactor
我正在尝试开发一个新的批与Spring批和jpa。当我尝试启动它时,我收到错误"嵌套异常是org.springframework.beans.factory.NoSuchBean定义异常:没有名为'entityManagerFactory'可用的bean" 我的pom.xml 我的数据源配置类: 我的存储库类: 我的实体类: pplication.properties: 如果我尝试启动应用程序,我
我正在开发一个新的应用程序(对我来说),我在启动时收到了无bean“entityManagerFactory”可用错误。其他经历过这种情况的人表示,如果我正确定义了数据源,这种情况就不会发生。让我困惑的是,Spring Boot/JPA或Flyway(我也在使用)坚持将特定的属性名称用于您的一个数据源。我不知道如果你有一个以上的人会怎么处理。我需要更改我们的申请。属性文件,以便从环境变量中获取值,
我想开发一个模块化的应用程序,使用MySql数据库,Java11和Spring启动。在我添加模块描述符之前,这个应用程序运行得非常好;所以我只能猜测我在module-info.java中丢失了一些东西,但我不知道它是什么。我感谢任何帮助。这是我的密码 波姆。xml 应用yml module-info.java 使用者JAVA UsersRepository.java 用户资源。JAVA 演示应用程
我在Spring中开发了一个简单的应用程序,我遇到了这个常见的问题,但是我找不到解决方案,因为在其他文章中提到的那些由于某种原因无法工作。 当我第一次运行应用程序时会触发错误,它是这样说的: 这是我的pom。xml 这是我的冬眠状态 我试图做的是开发一个Spring Boot应用程序,它使用hibernate连接到xampp提供的mysql数据库,但是这个错误给我带来了困难。
我正在开发一个小应用程序,只是为了自己尝试Spring Boot。它有五个不同的模块(eclipse项目): 模型——包含实体类、DTO和映射器以在它们之间切换 数据--包含存储库 服务——包含服务及其实现 reserve management--包含预订控制器和spring应用程序本身 人员管理-包含人员数据的控制器和Spring应用程序本身 如果我启动这两个应用中的任何一个,它们都可以正常运行
请求处理失败;嵌套的异常是org。springframework。豆。工厂NoSuchBeanDefinitionException:没有名为“transactionManager”的bean可用:没有为限定符“transactionManager”找到匹配的transactionManager bean-既没有限定符匹配,也没有bean名称匹配! 客户请求。JAVA 客户控制器 顾客道 spri
当我试图使用spring代码创建关系时,我得到了事务管理器错误。我正在我的项目中使用Mysql和Neo4j数据库。我尝试了不同的解决方法,但都解决不了。 noSuchBeanDefinitionException:没有名为“Transaction Manager”的bean可用:没有为限定符“Transaction Manager”找到匹配的PlatformTransactionManager b