泛型,通配符和超级/扩展接口

时间:2012-02-19 23:17:10

标签: generics interface entity wildcard

我有以下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 个答案:

答案 0 :(得分:4)

编译器非常清楚这里的错误(这是一个很好的改变!)。

您的第一次尝试是非法的,因为您无法扩展通配类型。

您的第二次尝试是非法的,因为您不能使用不同的类型绑定继承两次泛型接口。请注意,您的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>