Как я могу обернуть класс Model для Play / JPA универсальным репозиторием? - PullRequest
4 голосов
/ 16 ноября 2011

Мне не нравится работать с объектами моделей напрямую, потому что это нарушает инкапсуляцию. Вместо этого я предпочитаю Шаблон репозитория .

Когда я пытаюсь реализовать простой репозиторий

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(), она работает хорошо).

1 Ответ

2 голосов
/ 16 ноября 2011

Это не работает, потому что вы вызываете статический (класс) метод.

JPAEnhancer во время выполнения добавит метод в ваш класс (User), но полиморфизм отсутствуетдля типов / статических методов он всегда будет вызывать GenericModel.

Что вы можете попробовать сделать, это получить фактический параметрический тип с чем-то вроде

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

и метод invoke для этого класса ..

Надеюсь, это поможет ...

...