2011-11-16 27 views
4

我不喜歡直接使用模型對象,因爲這會破壞封裝。相反,我更喜歡Repository Pattern如何將Play/JPA的Model類與一個通用Repository進行封裝?

當我試圖實現一個簡單的倉庫

public abstract class BaseRepository<T extends Model> { 
    public T findOne(String query, Object... params) { 
     GenericModel.JPAQuery result = T.find(query, params); 
     return result.first(); 
    } 
} 
public class UserRepository extends BaseRepository<User>{} 

UserRepository repo = new UserRepository(); 
repo.findOne("byUsername", "test"); 

我得到的,因爲Java的方式一般或JPA註解的異常工作:

java.lang.UnsupportedOperationException: Please annotate your JPA model with 
@javax.persistence.Entity annotation. 
    at play.db.jpa.GenericModel.find(GenericModel.java:269) 
    at repositories.BaseRepository.findOne(BaseRepository.java:12) 

有沒有辦法解決? (不用說模型是正確註釋的,當我直接用User.find("byUsername", "test").first()就可以了)。

+0

你可以提供代碼示例,你實際上調用引發異常的'findOne()'嗎? – tmbrggmn

+1

@pHk - 'UserRepository repo = new UserRepository(); repo.findOne(「byUsername」,「testy」);' – ripper234

+0

這很奇怪。恐怕目前我沒有太多的幫助,但我很好奇爲什麼這會導致對GenericModel的靜態調用。 – tmbrggmn

回答

2

它不起作用,因爲您正在調用靜態(類)方法。

JPAEnhancer將在運行時將該方法添加到您的類(User),但類型/靜態方法沒有多態性,它將始終調用GenericModel類。

你能嘗試做的就是實際的參數類型的東西,如

ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass(); 
Class<?> aClass = (Class<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0]; 

,並在該類invoke方法..

希望幫助...

+0

這是我在你的回答後試過的代碼:https://gist.github.com/1370600當調用invoke()方法時,我得到一個'argument type mismatch'異常 - 可能它與elipsis有關在方法參數中。無論如何,目前我的應用似乎有點矯枉過正。 – ripper234

+0

試試這個,有點簡單 - > https://gist.github.com/1370677 – mericano1

+0

不錯。類型轉換中的泛型約束實際上沒有編譯,所以我放棄了它。這裏是一個工作完整的例子 - https://gist.github.com/1370851 – ripper234

相關問題