2015-05-12 2 views
1

Я знаю, что этот вопрос задавали часто, но я не могу найти решение. Как получить общее имя класса типа в репозитории, вложенном в Spring?Spring get generic type class

Вот это моя база хранилище

public interface UserRepository extends JpaRepository<User, Long>, IUserRepository<User>{ 
    User findByUsername(String username); 
} 

это интерфейс

public interface IUserRepository<T> { 
    public List<T> findAllValidEtSiteAndStructure(); 
} 

и, наконец, здесь реализация

public class UserRepositoryImpl<T> implements IUserRepository<T> { 

@PersistenceContext 
private EntityManager em; 

private Class<T> type; 

@Override 
public List<T> findAllValidEtSiteAndStructure() { 
    final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
    if (authentication instanceof UserAuthentication) { 
     final User currentUser = ((UserAuthentication) authentication).getDetails(); 
     return (List<T>) em.createQuery("FROM " + type.getName()+ " WHERE site=:site AND structure=:structure AND valid=:valid") 
       .setParameter("site", currentUser.getInstallation().getSite()) 
       .setParameter("structure", currentUser.getInstallation().getStructure()) 
       .setParameter("valid", true) 
       .getResultList(); 
    } 
    return null; 
} 
} 

как я могу получить type.name? Заранее спасибо

ответ

1

Общий ответ на Ваш вопрос можно увидеть в документации ->http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations в главе Пользовательские реализациях для Spring Data репозиториев

Но я думаю, что не должно быть необходимым в вашем случае. Вы должны иметь возможность сделать это следующим образом.

public interface UserRepository extends JpaRepository<User, Long> { 

    User findByUsername(String username); 

    List<User> findByStructureAndSiteAndValid(Structure structure, Site site, boolean valid); 
} 
+0

спасибо, это помогло мне много! – davidetrapani

1

В принципе, вы не можете получить общий тип из-за type erasure.

Что я хотел бы сделать, это добавить абстрактный метод UserRepositoryImpl, который возвращает соответствующий тип:

public abstract Class getType(); 

А потом я хотел бы создать конкретные экземпляры для UserRepositoryImpl, для которых тип уже известен во время компиляции. Например:

public class StudentRepository extends UserRepositoryImpl<Student> { 
    public Class getType() { 
    return Student.class; 
    } 
} 
0

Учитывая, что вы используете Spring Framework, используйте код сниппета, приведенную ниже, я проверил, и он работал отлично:

ResolvableType resolvableType = ResolvableType.forClass(UserRepository.class).as(JpaRepository.class); 
System.out.println(resolvableType.getGeneric(0));//User 
System.out.println(resolvableType.getGeneric(1));//Long