在 Spring Boot 中获取 EntityManager 的句柄

Posted

技术标签:

【中文标题】在 Spring Boot 中获取 EntityManager 的句柄【英文标题】:Obtaining handle to EntityManager in Spring Boot 【发布时间】:2015-11-08 07:27:58 【问题描述】:

有什么方法可以获取给定实体对象的 EntityManager 句柄?我正在使用带有 JPA 启动器的 spring boot 1.2.3,并且我正在使用 @configuration 进一步明确配置多个数据源

我检查了[resolved]SPRING BOOT access to entityManager,它似乎没有回答这个问题。

谢谢。

编辑:我添加了关于如何定义我的数据源的说明:

@Component
@Configuration
public class DataSources 
    @Bean
    @Primary
    @ConfigurationProperties(prefix="first.datasource")
    public DataSource getPrimaryDataSource() 
        return DataSourceBuilder.create().build();
    

    @Bean
    @ConfigurationProperties(prefix="second.datasource")
    public DataSource getSecondDataSource() 
        return DataSourceBuilder.create().build();
    

    @Bean
    @ConfigurationProperties(prefix="third.final.datasource")
    public DataSource getThirdFinalDataSource() 
        return DataSourceBuilder.create().build();
    

在我的 application.yml 我有以下部分

first.datasource:
  name: 'first_datasource',
  #other attributes...
second.datasource:
  name: 'second_datasource',
  #other attributes...
third.final.datasource:
  name: 'first_datasource',
  #other attributes...

到目前为止,我已经尝试了@Stephane 的两个建议,但我得到了NoSuchBeanDefinitionException

假设我的实体名为Customer,然后我尝试了

@Service
public class FooService 

    private final EntityManager entityManager;

    @Autowired
    public FooService(@Qualifier("customerEntityManager") EntityManager entityManager) 
        ...
    


不过我也试过了

@PersistenceContext(unitName = "customer") // also tried "customers" and "first_datasource"
private EntityManager entityManager;

没有运气。

【问题讨论】:

如果不了解您是如何配置 JPA 数据库的,这有点难说。通常你应该可以使用@PersistenceContext 并且你很高兴。您能告诉我们您是如何配置数据库的吗? 谢谢我知道了。仅当您需要主数据源以外的数据源时,您才需要提供 unitName。省略单元名称可以让您获得最终为我的目的工作的主要实体管理器。 【参考方案1】:

这取决于您如何配置它,但您是否尝试过注入 EntityManager 使用与创建它的工厂相对应的限定符?

这里是a sample project with two data sources。如果您想注入EntityManager 进行订购,只需在项目的任何Spring bean 中执行以下操作

@Service
public class FooService 

    private final EntityManager entityManager;

    @Autowired
    public FooService(@Qualifier("orderEntityManager") EntityManager entityManager) 
        ...
    


对于客户,请使用customerEntityManager

当然你也可以使用持久化单元名,也就是

@PersistenceContext(unitName = "customers")
private EntityManager entityManager;

@PersistenceContext(unitName = "orders")
private EntityManager entityManager;

查看项目配置了解更多详情。

【讨论】:

谢谢@Stéphane。在我没有定义persistence.xml的Spring-Boot的情况下,我如何找到持久性单元的名称?我尝试了多种猜测,但我得到了 NoSuchBeanDefinitionException 我很困惑。 Spring Boot 不支持多个实体管理器的自动配置,您必须自己配置。如果您有多个数据源,其中一个是@Primary,那么您的问题到底是什么? Boot 将仅在实体管理器上创建,因此只需添加 @PersistenceContext(或 @Autowired)即可。 我确信我缺少一些东西。无论如何,我在有关如何创建数据源的问题中添加了更多细节。我不知道这是否有帮助。谢谢。 就像我已经告诉你的那样,Spring Boot 不支持自动配置多个实体管理器,你必须自己配置。 所以你的项目有 3 个数据源和 ONE 实体管理器(在主数据源上)。如果你注入实体管理器(没有限定符,纯 @PersistenceContext 你会得到唯一存在的。你没有从那个开始有点奇怪)。如果您需要 3 个实体经理,请点击我提供的示例项目的链接。 嗨,斯蒂芬。感谢您的样品,这是非常好的工作!但是我有一个问题,为什么 Entity 和 Rspository 类必须在同一个包中?如果我想将它们拆分为不同的包,我该怎么办?

以上是关于在 Spring Boot 中获取 EntityManager 的句柄的主要内容,如果未能解决你的问题,请参考以下文章

如何在不从 spring-boot-starter-web 继承的情况下在 Spring Boot 中获取 ObjectMapper 实例?

如何在 Spring-Boot-REST 调用中获取用户信息?

在 Spring Boot 中获取请求标头

Spring Boot在aop中获取request对象

如何在 Spring Boot 中获取请求 URL

Spring/Boot - JWT 未在 GET 请求中获取