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

时间:2015-12-17 18:56:52

标签: java mysql spring hibernate jpa

我有一个带有多个实体管理器的JPA / hibernate设置。我想要做的是动态地将实体管理器注入由具有相同实体定义的多个模式使用的抽象类中 - 这些表在单个MySQL服务器中的不同数据库之间完全相同。我试图不写不必要的重复代码,但我似乎无法找到一种方法来动态注入持久化上下文而无需复制大量代码。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:0)

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

如果您想要选择要连接的实例,请在一个或多个配置文件中设置必要的密钥,然后使用它来获取连接池的必要连接属性。

如果你想拥有相同DAO的多个实例,可以使用限定bean和构造函数注入来获取适当的实体管理器(将所有其他工具/池创建抽象为方法)。

答案 1 :(得分:0)

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

通过使用带持久性unitName的@PerisstenceContext调用setEntityManager(EntityManager em)来实现神奇。 我不完全确定为什么会这样,但似乎可以解决问题。

这就是我的所作所为: AbstractJpaDao:

@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 ...
}

InheritedDao1:

@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;
    }
}

InheritedDao2:

@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);
    }
}