EJB - 如何使用具有多个持久性单元的CRUD代码

时间:2012-08-24 16:25:37

标签: generics java-ee persistence ejb entitymanager

我想用EJB装备我的EJB。

我有很多实体和多个持久性单元

我想实现一次CRUD方法并在不同的持久性单元上调用它们。

我尝试使用继承来实现这一点,但它无法正常工作。

CRUD课程是:

public class FormEBean<T> {

    protected EntityManager em;

    public EntityManager getEm() {
        return em;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }

    public String create(T entity) {
        try {
            em.persist(entity);
            em.flush();
            return null;
        } catch (Exception ex) {
            return ex.getLocalizedMessage();
        }
    }

    public void create(List<T> entityList) {
        for (T entity : entityList) {
            em.persist(entity);
        }
    }

    public void edit(T entity) {
        em.merge(entity);
    }

    public void edit(Set<T> entitySet) {
        Iterator<T> it = entitySet.iterator();
        while (it.hasNext()) {
            T entity = it.next();
            em.merge(entity);
        }
    }

    public void remove(T entity) {
        em.remove(em.merge(entity));
    }

    public void remove(T[] listaDaRimuovere) {
        for (T entity : listaDaRimuovere) {
            em.remove(em.merge(entity));
        }
    }

    public void remove(List<T> listaDaRimuovere) {
        for (T entity : listaDaRimuovere) {
            em.remove(em.merge(entity));
        }
    }
}

所以我试着用这种方式:

@Stateless
@Remote(MyEBeanRemote.class)
public class MyEBean extends FormEBean<MyEntityClass> implements MyEBeanRemote {

    @PersistenceContext(unitName = "siat-ejbPU")
    private EntityManager em;

    // code here
}

即使我没有任何错误,CRUD函数也不会影响我的DataBase。

相反,如果我将它们直接插入MyEBean,它的行为与预期的一样。

我不想在FormEBean中使用@PersistenceContext(unitName = "siat-ejbPU"),因为EJB可以使用不同的持久性单元。

有没有办法解决这个问题?

我可以用一种模式重用我的代码吗?

修改

这个问题的目的是找到一种解决方案,它可以在属于不同EJB模块且具有不同持久性单元的EJB中最大化CRUD代码重用。

在无状态会话bean中使用泛型方法似乎是一个很好的解决方案,但仅限于在同一个持久性单元中重用EJB的CRUD代码。

什么解决方案可以是持久性单元独立的(如果存在)?

3 个答案:

答案 0 :(得分:3)

您好,您可以使用setter方法:

@Stateless
@Remote(MyEBean.class)
public class MyEBean extends FormEBean implements MyEBeanRemote {

    final Logger logger = LoggerFactory.getLogger(MyEBean.class);

    @PersistenceContext(unitName = "siat-ejbPU")
    @Override
    public void setEmCrud(EntityManager em) {
        super.setEmCrud(em)
    }

为我工作。

答案 1 :(得分:0)

您需要使CRUD方法通用(创建/编辑/删除)。

名为 FormEBean 的类 NOT 应该是通用的。

如果您使方法通用而不是类,您可以实现它们一次并将它们与任何实体类一起使用。通用的crud方法可能如下所示:

public <T> T create(T someEntity) {
    em.persist(someEntity);
    return someEntity;
}

public <T> void create(Collection<T> entities) {
    for (T entity : entities) {
        em.persist(entity);
    }
}

public <T> void edit(T entity) {
    em.merge(entity);
}

public <T> void edit(Collection<T> entities) {
    for (T currentEntity : entities) {
        em.merge(currentEntity);
    }
}

将它们放在会话bean中,并在任何地方使用它们来操作任何实体。

/**
 *  Example managed bean that uses our
 *  stateless session bean's generic CRUD
 *  methods.
 *
 */

class ExampleManagedBean {

    @EJB
    MyCrudBeanLocal crudBean;

    public void createStuff() {
        // create two test objects
        Customer cust   =  createRandomCustomer();
        FunkyItem item  =  createRandomItem();
        // use generic method to persist them
        crudBean.create(cust);
        crudBean.create(item);
    }
}

这个答案正是我所描述的,并提供了示例代码:

另一个例子:

答案 2 :(得分:0)

我找到了解决问题的解决方案。

它基于jahroy的答案,但使用继承来处理多个persitence单位。

公共代码是基类(不是通用的,但是使用泛型方法):

    public class FormEBean {

        final Logger logger = LoggerFactory.getLogger(FormEBean.class);

        protected EntityManager emCrud;

        public EntityManager getEmCrud() {
            return emCrud;
        }

        public void setEmCrud(EntityManager em) {
            emCrud = em;
        }

        public <T> String create(T entity) {
            String exception = null;
            try {
                emCrud.persist(entity);
                emCrud.flush();
            } catch (Exception ex) {
                //ex.printStackTrace();
                exception = ex.getLocalizedMessage();
            }
            return exception;
        }

        public <T> void create(List<T> entityList) {
            for (T entity : entityList) {
                emCrud.persist(entity);
            }
        }

        public <T> void edit(T entity) {
            emCrud.merge(entity);
        }

        public <T> void edit(Set<T> entitySet) {
            Iterator<T> it = entitySet.iterator();
            while (it.hasNext()) {
                T entity = it.next();
                emCrud.merge(entity);
                emCrud.flush();
            }
        }

        public <T> void remove(T entity) {
            emCrud.remove(emCrud.merge(entity));
        }

        public <T> void remove(T[] listaDaRimuovere) {
            for (T entity : listaDaRimuovere) {
                emCrud.remove(emCrud.merge(entity));
            }
        }

        public <T> void remove(List<T> listaDaRimuovere) {
            for (T entity : listaDaRimuovere) {
                emCrud.remove(emCrud.merge(entity));
            }
        }
     }

...这是界面:

public interface FormEBeanRemote {
    public void setEmCrud(EntityManager em);
    public <T> String create(T entity);
    public <T> void create(List<T> entityList);
    public <T> void edit(T entity);
    public <T> void edit(Set<T> entitySet);
    public <T> void remove(T entity);
    public <T> void remove(T[] listaDaRimuovere);
    public <T> void remove(List<T> listaDaRimuovere);
}

EJB(无状态会话bean)如下所示:

@Stateless
@Remote(MyEBean.class)
public class MyEBean extends FormEBean implements MyEBeanRemote {

    final Logger logger = LoggerFactory.getLogger(MyEBean.class);

    @PersistenceContext(unitName = "siat-ejbPU")
    private EntityManager em;

    public EntityManager getEm() {
        return em;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }

    @PostConstruct
    public void postConstruct() {
        this.setEmCrud(em);
    }

...其中

@Remote
public interface MyEBeanRemote extends FormEBeanRemote {
......
}

请注意,EJB使用postConstruct方法设置entityManager,该委托被委派为在特定的持久性单元上执行CRUD操作。

到目前为止,它的工作方式就像一个魅力。

如果有人发现任何陷阱,请告诉我。