Java JPA/Hibernate动态注入实体管理器

Java JPA/Hibernate动态注入实体管理器,java,mysql,spring,hibernate,jpa,Java,Mysql,Spring,Hibernate,Jpa,我有一个带有多个实体管理器的JPA/hibernate设置。我试图做的是在一个抽象类中动态注入实体管理器,该抽象类由具有相同实体定义的多个模式使用——在单个MySQL服务器中,跨不同数据库的表完全相同。我试图不编写不必要的重复代码,但我似乎找不到一种方法来动态注入持久性上下文而不复制大量代码。有什么方法可以做到这一点吗?那么,您需要更改DAO实例中存在的EntityManager吗?如果是,我会说只需切换您的连接池即可 如果要选择要连接到哪个实例,请在一个或多个配置文件中设置必要的键,然后使用该

我有一个带有多个实体管理器的JPA/hibernate设置。我试图做的是在一个抽象类中动态注入实体管理器,该抽象类由具有相同实体定义的多个模式使用——在单个MySQL服务器中,跨不同数据库的表完全相同。我试图不编写不必要的重复代码,但我似乎找不到一种方法来动态注入持久性上下文而不复制大量代码。有什么方法可以做到这一点吗?

那么,您需要更改DAO实例中存在的EntityManager吗?如果是,我会说只需切换您的连接池即可

如果要选择要连接到哪个实例,请在一个或多个配置文件中设置必要的键,然后使用该键获取连接池所需的连接属性


如果您想拥有同一DAO的多个实例,请使用合格的bean和构造函数注入,让适当的实体管理器将工厂/池创建等所有内容抽象到方法中。

我最终创建了一个包含所有基本列表、更新、,删除方法并通过另一个抽象DAO进行扩展,我在其中为该特定集合设置了实体管理器。任何扩展最后一个DAO的DAO都将具有与之关联的正确带注释的实体管理器。从那时起,我就能够重用我的模型,我所要做的就是在我的服务层上扩展正确的DAO

通过使用@PerisstenceContext和持久化单元名调用setEntityManagerEntityManager em,可以实现神奇的效果。我不完全确定这为什么有效,但似乎起到了作用

以下是我所做的: 摘要JPADAO:

@MappedSuperclass
public class AbstractJpaDao <T>{
    private Class<T> clazz;
    protected EntityManager entityManager;

    public final void setClazz(final Class<T> clazzToSet) {
        this.clazz = clazzToSet;
    }

    @Transactional
    public T getById(final long id) {
        return entityManager.find(clazz, id);
    }
    //... all the others ...
}
继承的DAO1:

@MappedSuperclass
public class InheritedDao <T> extends AbstractJpaDao <T>{
    //This is what allows me to inject the entityManager by its annotation
    @PersistenceContext(unitName = "myPU")
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
}
继承的DAO2:

@MappedSuperclass
public class OtherInheritedDao <T> extends AbstractJpaDao <T>{
    //This is what allows me to inject the entityManager by its annotation
    @PersistenceContext(unitName = "otherPU")
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
}
服务1:

@Service
@Transactional(readOnly = true)
public class MyService extends InheritedDao<MyModel> {
    public MyService() {
        setClazz(MyModel.class);
    }
}
服务2:

@Service
@Transactional(readOnly = true)
public class OtherService extends OtherInheritedDao<MyModel> {
    public OtherService() {
        //same model as used in MyService
        setClazz(MyModel.class);
    }
}