Общая проблема Java с Hibernate, как обработать T get (K id) - PullRequest
3 голосов
/ 28 декабря 2011

Мой GenericDao имеет:

 public T get(K id);

Теперь мой GenericDaoImpl имеет:

public T get(K id) {
    return super.getHibernateTemplate().get(???, id);
  }

Я попытался:

get(T.class, id);

Но я получаю ошибку времени компиляции:

cannot select from a type variable

Можно ли как-то правильно это сделать?

Ответы [ 4 ]

3 голосов
/ 28 декабря 2011

Из-за стирания типа это невозможно.
Вам нужно взять экземпляр Class в качестве параметра.

1 голос
/ 25 января 2013

Моя реализация:

public abstract class DAOImpl <T, PK extends Serializable> implements DAO<T, PK>  {


  protected abstract Class<T> getEntityClass();

  public T findById(PK id){
    return (T)getHibernateTemplate().get(getEntityClass(),id);
  }

  protected DetachedCriteria createDetachedCriteria(){
    return DetachedCriteria.forClass(getEntityClass());
  }

  @SuppressWarnings("unchecked")
  public List<T> findAll(){
    return  getHibernateTemplate().findByCriteria(createDetachedCriteria());
   }

}
1 голос
/ 28 декабря 2011

Вам необходимо построить свой GenericDao таким образом, чтобы он мог выяснить, с каким конкретным типом сущности он был параметризован.Например, SomeEntityDaoImpl должен иметь возможность выяснить, что его тип сущности имеет вид SomeEntity.class.

Либо

  1. добавить абстрактный метод getEntityClass в GenericDao,и переопределите этот метод в каждом DaoImpl для предоставления соответствующего класса сущности, или

  2. используйте рефлексивный метод для автоматического поиска параметра типа (я использовал MoreTypes.getGenericSupertype() из Google Guice,затем ParameterizedType.getActualTypeArguments().)

Тогда вам не нужно будет передавать литерал Class для get (), потому что DaoImpl может просто вызвать getEntityClass () самостоятельно.

0 голосов
/ 30 декабря 2011

Если GenericDaoImpl является абстрактным, и вся реальная реализация имеет ограничения T и K, то вы можете получить значение параметров типа, используя отражение:

abstract class GenericDaoImpl<K, T> {

  public T get(K id) {
    Class<?> valueClazz = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    return super.getHibernateTemplate().get(valueClazz, id);
  }

}

class StringDao extends GenericDaoImpl<Integer, String> {
}

Я создал слегка измененный пример на ideone , но он просто печатает класс типов, в данном случае String.

Это работает только тогда, когда StringDao (и все другие DAO)это прямой подкласс GenericDaoImpl, поэтому он немного хрупкий.И, как я уже сказал, это НЕ будет работать, если GenericDaoImpl не является абстрактным, а предназначен для непосредственного использования.В этом случае я думаю, что вы должны подумать, является ли то, что вы делаете, правильным подходом.По моему опыту, DAO, которые являются такими общими, не очень хорошо работают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...