Обобщения, подстановочные знаки и супер / расширяемые для интерфейсов - PullRequest
2 голосов
/ 20 февраля 2012

У меня есть следующая иерархия наследования сущностей jpa:

  • абстрактный аккаунт
  • ChildminderAccount продлевает счет
  • ParentAccount расширяет счет

Я хотел бы иметь такую ​​же иерархию наследования с моими интерфейсами DAO, то есть три интерфейса:

  • AccountDAO
  • ChilminderAccountDAO
  • ParentAccountDAO

Вот, например, мой базовый интерфейс DAO, который будет содержать методы, общие для интерфейсов ChilminderAccountDAO и ParentAccountDAO:

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import com.bignibou.domain.Account;

public interface AccountDAO extends CrudRepository<Account, Integer> {

    @Modifying
    @Transactional
    @Query("UPDATE Account a SET a.accountValidated = false WHERE a.accountToken = ?1")
    int deactivateAccountFromToken(String accountToken);

    @Modifying
    @Transactional
    @Query("UPDATE Account a SET a.accountValidated = true WHERE a.accountToken = ?1")
    int reactivateAccountFromToken(String accountToken);

    @Query("SELECT COUNT(a) FROM Account a WHERE a.accountEmailAddress = :accountEmailAddress")
    long checkIfEmailAddressAlreadyExists(@Param("accountEmailAddress") String accountEmailAddress);

    Account findByAccountToken(@Param("accountToken") String accountToken);

    Account findByAccountEmailAddress(@Param("accountEmailAddress") String accountEmailAddress);
}

Затем я попытался определить мой интерфейс ChildminderDAO следующим образом: public interface ChildminderAccountDAO extends CrudRepository<? super Account, Integer>, AccountDAO, что приводит к:

Тип ChildminderAccountDAO не может расширяться или реализовываться CrudRepository. Супертип может не указывать любой подстановочный знак

я тоже пробовал: public interface ChildminderAccountDAO extends CrudRepository<ChildminderAccount, Integer>, AccountDAO, что приводит к:

Интерфейс CrudRepository не может быть реализован более одного раза с разные аргументы: CrudRepository и CrudRepository

Ничего не работает, и я не уверен, как указать обобщенные / подстановочные знаки для моих подчиненных интерфейсов, чтобы я оставлял методы общими для обоих в суперинтерфейсе и позволял подчиненным интерфейсам работать со своими соответствующими типами сущностей, т.е. ChildminderAccount и ParentAccount.

Может кто-нибудь, пожалуйста, дайте мне знать, как определить мои подчиненные интерфейсы?

1 Ответ

4 голосов
/ 20 февраля 2012

Компилятор достаточно ясно понимает, что здесь не так (что делает хорошее изменение!).

Ваша первая попытка недопустима, поскольку вы не можете расширять тип с подстановочными знаками.

Вашвторая попытка недопустима, потому что вы не можете дважды наследовать универсальный интерфейс с разными привязками типов.Обратите внимание, что ваш ChildminderAccountDAO будет расширять как CrudRepository<ChildminderAccount, Integer>, так и AccountDAO, а сам AccountDAO расширяет CrudRepository<Account, Integer>.

. Подход, который вам нужно использовать, заключается в том, чтобы сделать AccountDAO общим для типасчета.Он может использовать свою переменную типа в предложении extends для общего расширения CrudRepository.Подклассы могут затем связать этот параметр типа с определенными типами.Нравится:

public interface AccountDAO<A extends Account> extends CrudRepository<A, Integer>

public interface ChildminderAccountDAO extends AccountDAO<ChildminderAccount>

public interface ParentAccountDAO extends AccountDAO<ParentAccount>
...