2015-07-25 3 views
0

Как я могу использовать @Query в @NoRepositoryBean методах с @MappedSuperclass?Весна JPA NoRepositoryBean Запросы

У меня есть @MappedSuperclass Temporal (Basis имеет идентификатор длиной)

@MappedSuperclass 
public abstract class Temporal extends Basis<Long> { 

    private Long temporalCode; 
    private Date dateBegin; 
    private Date dateEnd; 
    // getters/setters 
} 

и @NoRepositoryBean TemporalRepository

@NoRepositoryBean 
public interface TemporalRepository<T extends Temporal> extends JpaRepository<T, Long> { 
// this two are ok 
    List<T> findByTemporalCode(Long temporalCode); 
    List<T> findByTemporalCodeAndDateBeginBeforeAndDateEndAfter(Long temporalCode, Date dateBegin, Date dateEnd); 

// query not working because Temporal is not an @Entity 
// @Query("select t from Temporal t 
//   where (t.dateBegin < ?1 or t.dateBegin is null) 
//   and (t.dateEnd < ?1 or t.dateEnd is null) ") 
// List<T> findByDate(Date date); 
} 

Обновление:
Например, у меня есть временная организация работник :

@Entity 
public class Worker extends Temporal { 
// fields and methods here 
} 

public interface WorkerRepo extends TemporalRepository<Worker> { 
// Looks like it will work but I don't want to write the same method in each TemporalRepository subclass 
// @Query("select w from Worker w where (w.dateBegin < ?1 or w.dateBegin is null) and (w.dateEnd < ?1 or w.dateEnd is null) ") 
// List<Worker> findByDate(Date date); 
} 
+0

рабочих средств? вы получаете какое-то исключение или что-то в этом роде. – Amogh

+0

Я думаю, что это не сработает, вы можете писать только методы в интерфейсе '@ NoRepositoryBean' без @query, а позже определить другой интерфейс репозитория без' @ NoRepositoryBean' и использовать расширения с помощью 'TemporalRepository 'интерфейс и переопределить методы. – Amogh

+0

Не работает означает получение исключения при запуске приложения. – DimaIT

ответ

2

Фактически вы можете использовать выражения SpEL для него. Spring Data JPA reference
Таким образом, мы можем заменить имя суперкласса с #{#entityName}

Примером из ссылки:

@MappedSuperclass 
public abstract class AbstractMappedType { 
    … 
    String attribute 
} 

@Entity 
public class ConcreteType extends AbstractMappedType { … } 

@NoRepositoryBean 
public interface MappedTypeRepository<T extends AbstractMappedType> 
    extends Repository<T, Long> { 

    @Query("select t from #{#entityName} t where t.attribute = ?1") 
    List<T> findAllByAttribute(String attribute); 
} 

public interface ConcreteRepository 
    extends MappedTypeRepository<ConcreteType> { … } 

решения для моего примера:

@NoRepositoryBean 
public interface TemporalRepository<T extends Temporal> extends JpaRepository<T, Long> { 
    List<T> findByTemporalCode(Long temporalCode); 

    List<T> findByTemporalCodeAndDateBeginBeforeAndDateEndAfter(Long temporalCode, Date dateBegin, Date dateEnd); 

    @Query("select t from #{#entityName} t 
     where (t.dateBegin < ?1 or t.dateBegin is null) 
     and (t.dateEnd < ?1 or t.dateEnd is null)") 
    List<T> findByDate(Date dateBegin); 
} 
не
0

KI не думайте, что вы можете это сделать, потому что @NoRepositoryBean используется, чтобы сказать весне, что не создайте для прокси-сервера репозитория для этого интерфейса. Такой интерфейс используется для раскрытия некоторых дополнительных методов, отличных от конкретного интерфейса репозитория. В этом случае вы должны extend такой интерфейс, я возьму еще один пример, чтобы объяснить:

Рассмотрим меня Student и Teacher лицо:

Теперь у меня есть интерфейс, как:

@NoRepositoryBean 
public interface ReadOnlyRepository<T, ID extends Serializable> extends JpaRepository<T, ID> { 
    T findById(int id); 
} 

Теперь мы необходимо написать конкретный интерфейс репо:

public interface StudentRepository extends ReadOnlyRepository<Student, Long> { 
    //override the methods of `ReadOnlyRepository` with @query 
} 

public interface TeacherRepository extends ReadOnlyRepository<Teacher, Long> { 

//override the methods of `ReadOnlyRepository` with @query 
} 

Таким образом, можно вручную определить e запросы как ученика, так и учителя, просто объявив JPA с запросами Student.findById и Teacher.findById. Используя этот подход, вы можете легко создать индивидуальные базовые интерфейсы для вашего сценария приложения.

Так что @NoRepositoryBean используется, чтобы избежать создания репозиториев.

+0

Yep и первые два метода отлично работают со всеми репозиториями, которые расширяют TemporalRepository в моем примере. Но в findByDate() у меня сложная логика, поэтому мне нужно что-то вроде @Query для записи select с помощью скобок. Конечно, я могу написать findByDate() во всех подклассах TemporalRepository, которые будут представлять конкретные Entities, но эти методы будут делать то же самое. Вот почему мне нужен этот метод в TemporalRepository. – DimaIT

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