Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa 如何在运行时根据条件使用不同的EntityManager?_Jpa_Ejb_Cdi - Fatal编程技术网

Jpa 如何在运行时根据条件使用不同的EntityManager?

Jpa 如何在运行时根据条件使用不同的EntityManager?,jpa,ejb,cdi,Jpa,Ejb,Cdi,我的看法如下: 抽象类: public abstract class AbstractFacade<T> { private Class<T> entityClass; public AbstractFacade(Class<T> entityClass) { this.entityClass = entityClass; } protected abstract EntityManager getEnti

我的看法如下:

抽象类:

public abstract class AbstractFacade<T> {

    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    // other methods create(T), edit(T), ...
有没有办法做到这一点


我读过关于使用CDI with products方法的内容。

CDI生产者并没有那么难,请参见下面的示例

以下类是CDI限定符注释,用于区分实现

@Retention(RetentionPolicy.RUNTIME)
@Target({ TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR }) 
@Qualifier 
public @interface MyfirstPUQualifier {  }

@Retention(RetentionPolicy.RUNTIME)
@Target({ TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR }) 
@Qualifier 
public @interface MysecondPUQualifier {  }
下面是一个CDIBean,它注入不同的EntityManager并实现生产者方法,使这两个EntityManager可用于CDI,通过CDI限定符进行区分

@ApplicationScoped
class MYProducer {
    @PersistenceContext(unitName = "myfirstPU")
    private EntityManager firstEm;

    @PersistenceContext(unitName = "mysecondPU")
    private EntityManager secondEm;

    @Produces
    @RequestScoped
    @MyfirstPUQualifier
    public EntityManager produceMyfirstPU(){
        return firstEm;
    }


    @Produces
    @RequestScoped
    @MysecondPUQualifier
    public EntityManager produceMysecondPU(){
        return secondEm;
    }
}
下面显示了一个CDIBean,它同时注入两个EntityManager。这可以提取到一个抽象基类,因为其他DAO可能也需要它

@Stateless
public class FileDao {

    @Inject
    @MyfirstPUQualifier
    private EntityManager emFirst;

    @Inject
    @MysecondPUQualifier
    private EntityManager emSecond;

    public void myDaoMEthod(){
        final EntityManager em = getEntityManager();
        ...
    }

    private EntityManager getEntityManager(){
        if(condition1){
            return emFirst;
        }
        else if(condition2){
            return emSecond;
        }
    }
}
如果不考虑使用什么EntityManager,就不能使用FileDAOBean,因为无论如何都不应该在这个bean中决定

@Stateless
@LocalBean
public class FileBusiness {

    @EJB
    FilesDao fileDao;

    public void myMethod(){
        // FileDao will decide what entity manager to use
        fileDao.doStruff();
    }
}

CDI制作人并没有那么难,请参见下面的示例

以下类是CDI限定符注释,用于区分实现

@Retention(RetentionPolicy.RUNTIME)
@Target({ TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR }) 
@Qualifier 
public @interface MyfirstPUQualifier {  }

@Retention(RetentionPolicy.RUNTIME)
@Target({ TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR }) 
@Qualifier 
public @interface MysecondPUQualifier {  }
下面是一个CDIBean,它注入不同的EntityManager并实现生产者方法,使这两个EntityManager可用于CDI,通过CDI限定符进行区分

@ApplicationScoped
class MYProducer {
    @PersistenceContext(unitName = "myfirstPU")
    private EntityManager firstEm;

    @PersistenceContext(unitName = "mysecondPU")
    private EntityManager secondEm;

    @Produces
    @RequestScoped
    @MyfirstPUQualifier
    public EntityManager produceMyfirstPU(){
        return firstEm;
    }


    @Produces
    @RequestScoped
    @MysecondPUQualifier
    public EntityManager produceMysecondPU(){
        return secondEm;
    }
}
下面显示了一个CDIBean,它同时注入两个EntityManager。这可以提取到一个抽象基类,因为其他DAO可能也需要它

@Stateless
public class FileDao {

    @Inject
    @MyfirstPUQualifier
    private EntityManager emFirst;

    @Inject
    @MysecondPUQualifier
    private EntityManager emSecond;

    public void myDaoMEthod(){
        final EntityManager em = getEntityManager();
        ...
    }

    private EntityManager getEntityManager(){
        if(condition1){
            return emFirst;
        }
        else if(condition2){
            return emSecond;
        }
    }
}
如果不考虑使用什么EntityManager,就不能使用FileDAOBean,因为无论如何都不应该在这个bean中决定

@Stateless
@LocalBean
public class FileBusiness {

    @EJB
    FilesDao fileDao;

    public void myMethod(){
        // FileDao will decide what entity manager to use
        fileDao.doStruff();
    }
}

因为您似乎需要在每次调用时动态地决定选择哪一个EM,所以我只需重新设计
AbstractFacade.getEntityManager()
,以获取条件参数,并根据该返回结果,相关EM.CDI生产者可能不会在这里帮助您,因为它们是为您需要时决定注入什么(而您每次都需要动态地选择不同的一个)。因为您似乎需要在每次调用中动态地决定选择哪一个EM,所以我只需重新设计
AbstractFacade.getEntityManager()
获取条件参数并基于该返回值,相关EM.CDI生产者可能不会在这里为您提供帮助,因为它们是在您需要时提供的,在注入时决定注入什么(而您需要每次动态选择不同的一个)。