1

我想为我的 EJB 配备 CRUD 方法。

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

我想实现一次我的 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 函数对我的数据库也没有影响。

相反,如果我将它们直接插入到 MyEBean 中,它会按预期运行。

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

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

有没有一种模式可以用来重用我的代码?

编辑:

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

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

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

4

3 回答 3

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

为我工作。

于 2012-12-14T14:19:40.870 回答
0

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

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

如果您将方法设为通用而不是类,您可以实现它们一次并将它们与任何实体类一起使用。通用的 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);
    }
}

这个答案完全符合我的描述并提供了示例代码:

另一个例子:

于 2012-08-24T22:44:43.163 回答
0

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

它基于 jahroy 的回答,但使用继承来处理多个持久性单元。

通用代码是一个基类(不是泛型但具有泛型方法):

    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 操作。

到目前为止,它就像一个魅力。

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

于 2012-08-29T16:55:11.193 回答