当前位置: 首页 > 知识库问答 >
问题:

注入两个中的一个

严阳夏
2023-03-14

考虑拥有两个实体管理器工厂:

<bean id="writeEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">...</bean>
<bean id="readOnlyEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">...</bean>

然后,我希望有两个Beans,并向其中注入正确的持久性上下文:

<bean id="readOnlyManager" class="..MyDatabaseManager">
<bean id="writeManager" class="..MyDatabaseManager">

该bean看起来像:

public class MyDatabaseManager {

    private javax.persistence.EntityManager em;

    public EntityManager(javax.persistence.EntityManager em) {
        this.em = em;
    }
    ...
}

这显然不起作用,因为EntityManager不是bean,不能以这种方式注入:

No qualifying bean of type 'javax.persistence.EntityManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

如何在bean中限定正确的EntityManager?我曾经使用< code>@PersistenceContext注释,但是这并不可用,因为我需要注入它。

如何为此类Bean指定持久性上下文?

更新:我的问题是如何通过XML而不是通过注释注入带有限定符的PersistenceContext。

共有3个答案

章玮
2023-03-14

我认为您正在尝试将entityManager注入到您的Manager类中

public class MyDatabaseManager {

// where you need to qualify your injection    
private javax.persistence.EntityManager em;

    public EntityManager(javax.persistence.EntityManager em) {
        this.em = em;
    }
    ...
}

这是我项目的工作代码

>

  • META-INF文件夹中的Persistence.xml

     <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
         <persistence-unit name="PERSISTENCE_UNIT_T" transaction-type="JTA">
             <provider>foo.bar.PersistenceProvider</provider>
             <jta-data-source>jdbc/DB2</jta-data-source>
    
         </persistence-unit>
    
          <persistence-unit name="PERSISTENCE_UNIT_P" transaction-type="JTA">
             <provider>foo.bar.PersistenceProvider</provider>
             <jta-data-source>jdbc/DB2</jta-data-source>
    
         </persistence-unit> 
     </persistence>
    

    限定符接口类选择数据源

     @Qualifier
        @Retention(RetentionPolicy.RUNTIME)
        @Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD })
        public @interface SelectDataSource{}
    

    EntityManager 类

    公共类EntityManager{

         public EntityManager() {
         }
    
         @Inject
         @SelectDataSource
         private EntityManager entityManager;
    
         // other entity manager methods
    
     }
    

    实体管理器提供程序类,用于提供基于上下文的持久性单元

    公共类EntityManager提供程序{

         @PersistenceContext(unitName = "PERSISTENCE_UNIT_T")
         private EntityManager entityManagerT;
    
         @PersistenceContext(unitName = "PERSISTENCE_UNIT_P")
         private EntityManager entityManagerP;
    
    
         @Produces
         @SelectDataSource
         EntityManager createEntityManager(InjectionPoint injectionPoint) {
    
             if (System.ENV.equalsIgnoreCase("p")) {
                 if (entityManagerP != null) {
    
                     return entityManagerP;
                 }
             }
    
             return entityManagerT;
         }
    
     }
    

    然后可以使用@Inject将EntityManager类注入到您喜欢的任何位置

    下面是一篇关于如何使用上下文依赖注入创建托管实体管理器的好文章https://www.sitepoint.com/cdi-weld-inject-jpa-hibernate-entity-managers/#usingaproducermethod

  • 桓修能
    2023-03-14

    假设你正在使用spring来管理交易,我会做的是2个不同的事务管理器,然后在我的服务中,我会使用最合适的事务管理器,如下所示:

    配置部分

    @Bean
    public LocalContainerEntityManagerFactoryBean writeEntityManagerFactory() {
    
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        //Your configuration here
        return factory;
    }
    
    @Bean(name={"writeTx"})
    public PlatformTransactionManager writeTransactionManager() {
    
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(writeEntityManagerFactory().getObject());
        return txManager;
    }
    
    @Bean
    public LocalContainerEntityManagerFactoryBean readEntityManagerFactory() {
    
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        //Your configuration here
        return factory;
    }
    
    @Bean(name={"readTx"})
    public PlatformTransactionManager readTransactionManager() {
    
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(readEntityManagerFactory().getObject());
        return txManager;
    }
    

    服务层

    @Transactional(value="readTx")
    public List<Object> read(){
        //Your read code here
    }
    
    @Transactional(value="writeTx")
    public void write(){
        //Your write code here
    }
    

    更新的答案我误解了这个问题。

    在您的配置类中,您可以定义:

    @Bean
        public LocalContainerEntityManagerFactoryBean writeEntityManagerFactory() {
    
            LocalContainerEntityManagerFactoryBean em  = new LocalContainerEntityManagerFactoryBean();
            em.setDataSource(dataSource());
            em.setPackagesToScan(new String[] { "models" });
            JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            em.setJpaVendorAdapter(vendorAdapter);
            em.setJpaProperties(hibProps());
            em.setPersistenceUnitName("writer");
            return em;
        }
        @Bean
        public LocalContainerEntityManagerFactoryBean readEntityManagerFactory() {
    
            LocalContainerEntityManagerFactoryBean em  = new LocalContainerEntityManagerFactoryBean();
            em.setDataSource(dataSource());
            em.setPackagesToScan(new String[] { "models" });
            JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            em.setJpaVendorAdapter(vendorAdapter);
            em.setJpaProperties(hibProps());
            em.setPersistenceUnitName("reader");
            return em;
        }   
    

    请参阅持久性单位名称

    然后,您可以通过以下方式注射它们:

    @PersistenceContext(unitName="writer")
    private EntityManager emWriter;
    
    @PersistenceContext(unitName="reader")
    private EntityManager emReader;
    

    我刚刚测试过,一切都很好

    安杰洛

    都浩淼
    2023-03-14

    坚持不懈xml(2个不同entitymanager的2个持久化单元,基于您的持久化提供程序,这里我使用HibernatePersistence)

    <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
       <persistence-unit name="pu1">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
       </persistence-unit>
    
       <persistence-unit name="pu2">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
       </persistence-unit>   
    </persistence>
    

    确保使用属性persistenceUnitName将持久性单元分配给实体管理器

        <bean id="writeEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                <property name="persistenceXmlLocation" value="classpath: of yout persistence xml" />
                <property name="persistenceUnitName" value="pu1" />  
                 .....other configuration of em..  
        </bean>
    

    其他 em 也是如此。

    现在,使用MyDatabase aseManager的构造函数注入来注入EntityManager(使用限定符名称例如。

    <bean id="mdm" class="MyDatabaseManager">
         <constructor-arg ref = "writeEntityManagerFactory"/>
    </bean>
    
     类似资料:
    • 现在只有一个嘲笑工作正常。另一个返回空指针异常。@Autowired和@Mock都为BCryptPasswordEncoder密码编码器提供空点;

    • 在我的应用程序中,我有以下代码可注册到GCM服务: 当我运行这段代码时,我在服务器中看到我的设备用2个不同的注册了两次,当服务器发送推送时,设备收到2条消息。 这是正常的事情吗?有没有办法确保只有一个?

    • 所以我有一个帮助命令,它会向您发送DM上的命令列表。发送后,我希望它在同一个@bot或@client.command中发送另一个嵌入。 @客户。command()异步定义帮助(ctx,成员:discord.member=None):

    • 批量订单 Purchorder 我已经试了一个星期了。我有这两个表,batchporder和purchord在batchporder表中,我需要插入一行,并获得传递给purchord插入的主id。在purchord中,我需要插入多行,因此我使用了insert\u batch。 控制器 模型 错误1 遇到PHP错误严重性:警告 消息:array_keys()要求参数1为数组,字符串为给定值 文件名:

    • 本文向大家介绍分享一个简单的sql注入,包括了分享一个简单的sql注入的使用技巧和注意事项,需要的朋友参考一下 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站

    • 问题内容: 是否可以在angularJS中将一个服务注入到另一个服务中? 问题答案: 是。遵循angularjs中的常规注入规则。 感谢@simon。最好使用数组注入以避免最小化问题。