这是对以下内容的后续操作:my previous question

我的以下代码行不起作用:

IAccount account = (AccountModel) new AccountRepository().getByEmail(emailaddress);


...getByEmail(...)的返回类型是Model<Account>,而AccountModel扩展了Model<Account>
然而,当我测试它时,我得到一个java.lang.ClassCastException: models.Model cannot be cast to models.AccountModel。我知道这是因为每个AccountModel都是一个Model<Account>,而不是相反。
有什么方法可以确保我可以解决此问题(或解决它)。

public class AccountRepository extends Repository<Account> {

    public AccountRepository() {
        super(Account.class);
    }

    public Model<Account> getByEmail(String emailAddress) {
        return this.getCustomHqlSingle("FROM Account a WHERE a.emailAddress = '" + emailAddress + "'");
    }
}

public abstract class Repository<T> implements Serializable {
    protected final Model<T> getCustomHqlSingle(String hql) {
        List<Model<T>> t = this.getCustomHqlList(hql);
        if (t != null && !t.isEmpty()) {
            return t.get(0);
        } else {
            return null;
        }
    }

    protected final List<Model<T>> getCustomHqlList(String hql) {

        Session session = SESSION_FACTORY.openSession();

        try {
            session.beginTransaction();
            List<T> entities = session.createQuery(hql).getResultList();
            List<Model<T>> result = new ArrayList<>();
            for (T t : entities) {
                result.add(this.getByEntity(t));
            }
            return result;
        } finally {
            session.close();
        }
}




对于将此问题标记为重复的人,让我从我的问题中改写以下句子:


我知道这是因为每个AccountModel都是一个Model<Account>,但是
并非相反。





我知道这是因为每个Dog都是一个Animal,而不是另一个
的方式。

最佳答案

您必须设计一种将Model<Account>转换为AccountModel的方法。从另一个问题中获取代码,您可以为此添加一个构造函数到AccountModel类中:

public class AccountModel extends Model<Account> implements IAccount {
    private static final AccountRepository REPOSITORY = new AccountRepository();

    public AccountModel(Account entity) {
        super(entity, REPOSITORY);
    }

    public AccountModel(Model<Account> model) { // <---
        super(model._entity, REPOSITORY);
    }

    // Method implementations...
}


然后更改您的AccountRepository类以从AccountModel返回getByEmail

public AccountModel getByEmail(String emailAddress) {
    return new AccountModel(this.getCustomHqlSingle("FROM Account a WHERE a.emailAddress = '" + emailAddress + "'"));
}


使用新的构造函数将Model<Account>转换为AccountModel



还有另一种选择。您可以让实现类实现一个抽象方法,该方法将返回所需的new Model<T>(...)类型,而不是在Repository中调用Model

public abstract class Repository<T, R> implements Serializable


...

public Repository(Class<T> repositoryClass) {

    if (!Repository._initiated)
        setup();

    this.cons = cons;
}

protected abstract R getModel(T entity, Repository<T> repo); // <--


然后在工厂方法中的某个位置:

public R getByFoo(...) {
   ...
   T t = session.get(_repositoryClass, ...);
   return getModel(t, this);
}


AccountRepository将返回新的AccountModel的位置:

public class AccountRepository extends Repository<Account, AccountModel> {

    public AccountRepository() {
        super(Account.class);
    }

    @Override
    protected AccountModel getModel(Account entity, Repository<Account> repo) {
        return new AccountModel(entity);
    }

}

09-07 16:17