Подтвердить что ты не робот

Как реализовать хранилище данных Spring для @MappedSuperclass

У меня есть JPA @MappedSuperClass и @Entity, расширяющие его:

@MappedSuperclass
public class BaseClass {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private Boolean active;

    //getters & setters

}

@Entity
public class Worker extends BaseClass{

    @Column
    private String name;

    //getters & setters

}

Поле active базового класса является флагом для дочерних объектов. В приложение должны быть загружены только активные. Затем я написал общий Spring интерфейс Data Proxy:

public interface Dao<T extends BaseClass, E extends Serializable> extends
        CrudRepository<T, E> {

    Iterable<T> findByActive(Boolean active);

}

И это один из интерфейсов, который должен быть для доступа к данным Worker, правильно расширив предыдущий:

@Transactional
public interface WorkerDao extends Dao<Worker, Long>{}

Итак, теперь в моем логическом слое я реализовал абстрактный класс, который обернет общий код для операций CRUD над моими сущностями. У меня будет служба для каждого из них, но я хочу просто наследовать от abstract. Я хочу связать конкретный репозиторий для каждой из сервисов и предоставить его суперклассу с помощью метода abstract. То, как реализуется мой суперкласс:

public abstract class GenericService<E extends BaseClass>{

    public abstract Dao<E, Long> getDao();

    //Here I've got some common operations for managing 
    //all my application classes, including Worker

}

Проблема заключается в том, что метод getDao() использует параметр класса E, который гарантированно будет только дочерним элементом BaseClass, а не javax.persistence.Entity. Когда я пытаюсь получить доступ к DAO из моей собственной реализации службы, я получаю эту ошибку:

Вызвано: java.lang.IllegalArgumentException: не удалось создать метамодель запроса для метода public abstract java.lang.Iterable com.mycompany.model.daos.interfaces.Dao.findByActive(java.lang.Boolean)!     на org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy $CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:93)

Причиняет: java.lang.IllegalArgumentException: не объект: класс com.mycompany.model.BaseClass     at org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)

Это имеет смысл, потому что E определяется как дочерний элемент BaseClass. Компилятор также позволяет мне написать это:

public abstract class GenericService<E extends BaseClass && Entity>

Однако я получаю сообщение об ошибке в дочерней службе, которая говорит, что класс Worker не совместим с сигнатурой для E. Кто-нибудь знает, как это решить?

4b9b3361

Ответ 1

Это просто вопрос аннотации абстрактного Repository как @NoRepositoryBean:

@NoRepositoryBean
public interface Dao<T extends BaseClass, E extends Serializable> extends
        CrudRepository<T, E> {

    Iterable<T> findByActive(Boolean active);

}

Таким образом, Spring полагается на реализацию базового репозитория для выполнения метода findByActive.

Что касается проблемы ограничения типа аннотации, невозможно объявить ограниченный тип аннотации. См. Ответы ниже.

См. также: