Hibernate继承hql类型

Hibernate inheritance hql type

我在hibernate中有dao继承,这里是代码:

public class BaseDaoImpl<T> implements BaseDao<T> {
    ...
    protected T findSingle(String hql,Object... params){
      List<T> list = find(hql,params);
      if(list == null || list.isEmpty()){
          return null;
      }
      if(list.size() > 1){
          logger.debug("HQL: {} does not return single element.",hql);
      }
      logger.info("find single: "+list.get(0));
      return list.get(0);
  }
}

用户道:

public interface UserDao<T extends User> extends BaseDao<T> {
  ...
  public T getUserByUsername(String username);
}

我有一个域 class 用户和两个子 class 用户:客户和销售。 我有两个 dao classes 相应地用于 Customer 和 Sales。

用户道:

public class UserDaoImpl<T extends User> extends BaseDaoImpl<T> implements UserDao<T>,BaseDao<T> {
  public T getUserByUsername(String username) {
    return findSingle("from User user where user.username = ?",username);
  }
}

客户道:

public class CustomerDaoImpl extends UserDaoImpl<Customer> implements CustomerDao {
  private static Logger logger = LoggerFactory.getLogger(CustomerDaoImpl.class);
  public Double getDeposit(Integer id) {
      Customer customer = get(Customer.class,id);
      if(customer != null){
          return customer.getDeposit();
      }
      return 0D;
  }
}

销售道:

public class SalesRepDaoImpl extends UserDaoImpl<SalesRep> implements SalesRepDao{

}

我的问题是,当我使用 customerDap 使用销售用户名(拥有该用户名的用户是 SalesRep 的实例,而不是客户)调用方法 getUserByUsername()(继承自 BaseDaoImpl)时,它抛出 java.lang.ClassCastException,它抱怨无法将 SalesRep 转换为 Customer。当我使用 customerDao 查询数据库并且它使用泛型类型来确保 CustomerDao 中使用的 T 应该是一个 Customer 时,BaseDaoImpl 中的 findSingle() 方法如何 return SalesRep 的一个实例在这种情况下,我认为它应该 return null 因为没有客户有用户名。

首先 -> 我假设您使用休眠继承策略。

查询 "from User" 休眠不允许神奇地知道您只在搜索客户。您必须更改查询或您的整体机制。

示例解决方案

public class UserDaoImpl<T extends User> extends BaseDaoImpl<T> implements UserDao<T>,BaseDao<T> {

    protected Class<T> entityClass;

    public UserDaoImpl(Class<T> entityClass) {
        this.entityClass = entityClass;
    }   
    public T getUserByUsername(String username) {
        return findSingle("from " + getEntityName() + " entity where entity.username = ?",username);
    }

    protected String getEntityName() {
        return entityClass.getSimpleName();
    }
}

如果不单独使用UserDaoImpl,可以使用例如TypeTools在运行时继承泛型