2015-04-13 5 views
0

У меня есть общий класс репозитория, который выглядит следующим образом:Как построить общий репозиторий сущностей в Java

public class HibernateRepository<E extends Object, EId> 
     implements EntityRepository<E, EId> { 

    // Many things that are working fine  

    @Override 
    public E getById(EId id) { 
     return entityManager.getReference(E.class, id); // <<< Error here! 
    } 
} 

Метод getById() предполагается вернуть определенный экземпляр объекта с учетом его Id. Что-то очень тривиально во многих других ситуациях, но не в этом, так как возвращается компилятор:

Illegal class literal for the type parameter E 

Обратите внимание, что я не хотите передать нужный класс методу, так как я уже делал это в определение класса.

Использование для этого класса может быть:

public class MyClassRepositoryHibernate 
     extends HibernateRepository<MyClass, Long> { 
} 

Теперь это новое хранилище работает на MyClass экземпляров и Id набирается Long.

Возможно ли это на Java?

ответ

2

Вам необходимо передать фактический тип класса конструктору вашего HibernateRepository и использовать его во всех своих методах. JVM не знает, что такое «E» во время выполнения, поэтому вам нужно предоставить конкретный тип класса.

Вы можете убедиться, что вы не создаете экземпляр объекта неправильно с помощью универсального типа параметра в конструкторе, например:

public class HibernateRepository<E extends Object, EId> 
    implements EntityRepository<E, EId> { 
    private Class<E> clazz; 

    public HibernateRepository(Class<E> clazz) { 
     this.clazz = clazz; 
    } 

    @Override 
    public E getById(EId id) { 
     return entityManager.getReference(clazz, id); // <<< Error here! 
    } 
} 

боль, а необходимость из-за типа стирания.

+0

Боли действительно, но решена моя проблема! Благодаря! – AlexSC

0

Тип будет удален после компиляции и, следовательно, недоступен. Это называется Тип Erasure. Вы должны передать объект класса где-нибудь.

+0

Я передаю его в объявлении класса. Разве этого недостаточно? – AlexSC

+0

Нет, технически вы этого не делаете. Эта информация удаляется после компиляции и неизвестна во время выполнения. Вот как генерики реализуются в java. – atamanroman

+0

Если вы подклассифицируете 'HibernateRepository' и укажите конкретный тип для' E' в подклассе **, информация будет доступна ** и может быть восстановлена. См. Например, «GenericTypeResolver» от Spring. –

Смежные вопросы