问题描述
我不喜欢直接使用模型对象,因为这会破坏封装。相反,我更喜欢。
I don't like working with models objects directly, because this breaks encapsulation. Instead, I prefer the Repository Pattern.
我尝试实现一个简单的存储库
When I try to implement a simple 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注释的工作方式,我得到了异常:
I get exceptions because of the way java's generic or JPA annotations work:
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()
它运作良好。)
(Needless to say the model is properly annotated, and when I use it directly with say User.find("byUsername", "test").first()
it works well).
推荐答案
它不起作用,因为你正在调用静态(类)方法。
It does not work because you are calling the static (class) method.
将在运行时添加方法对于你的类(用户),但类型/静态方法没有多态性,它总是会调用GenericModel。
The JPAEnhancer will at run time add the method to your class (User) but there is no polymorphism for types / static methods, it will always call the GenericModel one.
你可以尝试要做的是获得实际的参数类型,例如
What you can try to do is get the actual parametric type with something like
ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass();
Class<?> aClass = (Class<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0];
以及该类的调用方法..
and the invoke method on that class..
希望有帮助......
Hope that helps...
这篇关于如何使用通用存储库包装Play / JPA的Model类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!