Generics 接口的泛型、通配符和超级/扩展

Generics 接口的泛型、通配符和超级/扩展,generics,interface,entity,wildcard,Generics,Interface,Entity,Wildcard,我有以下jpa实体继承层次结构: 摘要帐户 ChildminderAccount扩展帐户 父帐户扩展帐户 我希望与我的DAO接口具有相同类型的继承层次结构,即三个接口: 会计道 奇明达 ParentAccountDAO 例如,我的基本DAO接口将包含ChilminderAccountDAO和ParentAccountDAO接口通用的方法: import org.springframework.data.jpa.repository.Modifying; import org.spring

我有以下jpa实体继承层次结构:

  • 摘要帐户
  • ChildminderAccount扩展帐户
  • 父帐户扩展帐户
我希望与我的DAO接口具有相同类型的继承层次结构,即三个接口:

  • 会计道
  • 奇明达
  • 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);
}
import org.springframework.data.jpa.repository.Modifying;
导入org.springframework.data.jpa.repository.Query;
导入org.springframework.data.repository.crudepository;
导入org.springframework.data.repository.query.Param;
导入org.springframework.transaction.annotation.Transactional;
导入com.bignibou.domain.Account;
公共接口AccountDAO扩展了Crudepository{
@修改
@交易的
@查询(“更新帐户a集合a.accountValidated=false,其中a.accountToken=?1”)
int deactivateAccountFromToken(字符串accountToken);
@修改
@交易的
@查询(“更新帐户a集合a.accountValidated=true,其中a.accountToken=1”)
int-accountfromtoken(字符串accountToken);
@查询(“从帐户a中选择计数(a),其中a.accountEmailAddress=:accountEmailAddress”)
长checkIfEmailAddressAlreadyExists(@Param(“accountEmailAddress”)字符串accountEmailAddress);
Account findByAccountToken(@Param(“accountToken”)字符串accountToken);
Account FindByaAccountMailAddress(@Param(“accountEmailAddress”)字符串accountEmailAddress);
}
然后,我尝试将我的ChildminderDAO接口定义如下:
公共接口ChildminderAccountDAO扩展了crudepository编译器已经非常清楚这里的错误(这是一个很好的改变!)

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

您的第二次尝试是非法的,因为您不能使用不同的类型绑定两次继承泛型接口。请注意,您的
ChildminderAccountDAO
将扩展
crudepository
AccountDAO
,并且
AccountDAO
本身扩展
crudepository

您需要使用的方法是使
AccountDAO
本身对帐户类型具有通用性。它可以在extends子句中使用其类型变量,以一般方式扩展
crudepository
。然后子类可以将该类型参数绑定到特定类型。比如:

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

public interface ChildminderAccountDAO extends AccountDAO<ChildminderAccount>

public interface ParentAccountDAO extends AccountDAO<ParentAccount>
公共接口AccountDAO扩展了crudepository
公共接口ChildminderAccountDAO扩展了AccountDAO
公共接口ParentAccountDAO扩展了AccountDAO