JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Object Relational Mapping » JPA  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to postflat modego to previous topicgo to next topic
本主題所含的標籤
作者 尋找可測試的 JSR330 @Inject + JPA + DAO 最佳實作
smallufo





發文: 57
積分: 2
於 2010-03-21 15:59 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
尋找 JSR330 @Inject + JPA + DAO 最佳實作?

我之前一直使用 Spring + Hibernate , 最近想改用 JPA + DAO , 因為 Spring 對 multiple persistence units 支援度不佳(幾乎是無,若有,似乎得很麻煩地 hack)
使我思考放棄 Spring , 直接使用 JSR 330 的 @javax.inject.Inject 來做 DI

廢話不多說,直接看 Code

1
2
3
4
public interface PersonDao
{
  public Person get(long id);
}

↑這是最簡單的DAO ,我仍使用DAO是因為我相信他仍有存在的必要,而且來自 Spring 陣營大概也習慣會加上這層

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class PersonDaoImpl implements PersonDao , Serializable
{
  @PersistenceContext(unitName = "test", type = PersistenceContextType.EXTENDED)
  EntityManager entityManager ;
 
  public PersonDaoImpl()
  {
  }
  
  @Override
  public Person get(long id)
  {
    return entityManager .find(Person.class , id);
  }
}

↑DAO 的實作
在 Spring , EntityManagerFactory 由 Spring 管理,因此可以直接透過 @PersistenceContext 注入 EntityManager , 我希望此 Dao實作可以不用修改就可以拿到 Spring 上面跑,所以保留此種寫法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class PersonDaoImplTest extends TestCase
{
  @Inject 
  protected PersonDao personDao;
  
  @Override
  protected void setUp() throws Exception
  {
    //personDao = new PersonDaoImpl();
  }
  
  public void testGet()
  {
    System.out.println("personDao = " + personDao);
    Person p = personDao.get(1);
    System.out.println("p = " + p);
  }
}

↑這是 JUnit TestCase

好了,問題來了,其實到這裡一看就知道,這個 TestCase 拿不到 PersonDao
因為 Junit 認不得 JSR330 的 @Inject , 這裡的 personDao 必定是 null

除非,手動在 setUp() 內 new 出 PersonDaoImpl() , 也就是被我 comment 起來的那行
但是在 PersonDaoImpl 內的 entityManager 仍然是 null
因此仍然 test failed

我曾經試過 extends UnitilsJUnit3 (from org.unitils)
但是他是針對 EntityManagerFactory 去注入,而似乎無法再把結果注入到 Dao

請問還有什麼方法可以成功 pass 這個測試呢?

其實我可以直接把 PersonDaoImpl 的 constructor 改寫:
1
2
3
4
5
  public PersonDaoImpl()
  {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");
    entityManager = emf.createEntityManager();
  }

這樣的確可以 pass
但是我希望是由 Junit 或是某個 framework 注入 EntityManager , 而不是手動產生


reply to postreply to post
話題樹型展開
人氣 標題 作者 字數 發文時間
2043 尋找可測試的 JSR330 @Inject + JPA + DAO 最佳實作 smallufo 1939 2010-03-21 15:59
1800 Re:尋找可測試的 JSR330 @Inject + JPA + DAO 最佳實作 mylee 327 2010-03-22 08:10
1735 Re:尋找可測試的 JSR330 @Inject + JPA + DAO 最佳實作 smallufo 372 2010-03-22 09:46
1849 Re:尋找可測試的 JSR330 @Inject + JPA + DAO 最佳實作 swpoker 172 2010-04-15 09:19
» JWorld@TW »  Object Relational Mapping » JPA

reply to postflat modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8