本文介绍了如何使用通用存储库包装Play / JPA的Model类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不喜欢直接使用模型对象,因为这会破坏封装。相反,我更喜欢。

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类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 03:26