2012-08-24 49 views
1

我想爲我的EJB添加CRUD方法。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)); 
     } 
    } 
} 

所以我這樣tryed:

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

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

    // code here 
} 

即使我沒有得到任何錯誤,CRUD功能對我的數據庫沒有影響。

相反,如果我直接將它們插入MyEBean,它的行爲如預期。

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

有沒有辦法解決這個問題?

是否有我可以用來重用我的代碼的模式?

編輯:

這個問題的目的是找到最大化在屬於不同EJB模塊和具有不同的持久性單元的EJB CRUD代碼重用的溶液。

在無狀態會話bean中使用泛型方法似乎是一個很好的解決方案,但只適用於在同一持久性單元中爲EJB重用CRUD代碼。

什麼解決方案可以是獨立的持久性單元(如果存在的話)?

回答

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,該entityManager被委託在特定的持久性單元上執行CRUD操作。

到目前爲止,它的工作就像一個魅力。

如果有人發現任何缺陷,請讓我知道。

+0

這看起來不錯。它應該允許您編寫一次CRUD方法,併爲每個持久性單元使用一個_stateless會話bean_。這裏有一些想法/建議:1.)你可能想要使_FormEBean_抽象。它看起來不像是要實例化的。 2。)我將在您的CRUD方法中替換_Set _和_List _和_Collection _。 _List_和_Set_實現_Collection_,這允許它們在這裏被視爲相同。 – jahroy

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

這個答案不正是我所描述並提供了示例代碼:

又如:

+0

謝謝,可以使用泛型方法而不是泛型類,但如果我理解正確:如果我使用接口,我將不得不實現所有ejBeans(不保存代碼)的泛型方法;你能否詳細說明一個類處理CRUD操作的問題?我如何在ejBeans中使用它?通過繼承?無論如何如何處理entityManager? – maxqua72

+0

@ maxqua72 - 您只需使用通用的crud方法實現一個_Stateless Session Bean_。你可以使用這個會話bean來處理所有實體的數據庫操作。查看上面的第一個鏈接。它從字面上完全符合我的建議並提供代碼示例。 – jahroy

+0

好的,我現在明白了,只有使用一個持久性單元纔是完美的解決方案。當我有很多EJB模塊並且每個模塊都有自己的持久性單元時,我應該爲每個ejb模塊(針對每個持久性單元)實現一個具有通用方法的類,因此例如10個EJB模塊意味着重複10次相同的代碼通用方法。有沒有辦法爲持久性單元獨立解決方案(這是我的意思是在我原來的問題)? – maxqua72

2

嗨,你可以使用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) 
    } 

爲我工作。

相關問題