我想用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代码。
什么解决方案可以是持久性单元独立的(如果存在)?
答案 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操作。
到目前为止,它的工作方式就像一个魅力。
如果有人发现任何陷阱,请告诉我。