Inheritence using java generics not working as expected

Question

I am trying to use inheritence and generics to create my application, but it doesn't seem to work the way I expect it to. I'll show you what I mean (TL;DR at the bottom):

public interface IModel extends Serializable {
    public int save();
    public void update();
    public void delete();
}

// <T> is a JPA annotated entity/class
@SuppressWarnings("serial")
public abstract class Model<T> implements IModel {
    private final Repository<T> _repository;
    protected T _entity;

    public Model(T entity, Repository<T> repository) {
        this._entity = entity;
        this._repository = repository;
    }

    public int save() {
        return _repository.save(_entity);
    }
    ...
}

This is implemented in for example my AccountModel, which is a Model with generic Account (which is a JPA entity) and which implements IAccount.

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

    public AccountModel(Account entity) {
        super(entity, REPOSITORY);
    }
    // Method implementations...
}

My generic Repository looks like this:

public abstract class Repository<T> implements Serializable {

    private static SessionFactory SESSION_FACTORY;
    private final Class<T> _repositoryClass;
    private static boolean _initiated = false;

    public Repository(Class<T> repositoryClass) {

        if (!Repository._initiated) 
            setup();

        this._repositoryClass = repositoryClass;
    }

    private void setup() {
        // logics
        Repository._initiated = true;
    }

    public final Model<T> getById(int id) {

        Session session = SESSION_FACTORY.openSession();

        try {
            session.beginTransaction();
            T t = session.get(_repositoryClass, id);
            return new Model<T>(t, this); // As suggested by @Vlad
        }
        finally {
            session.close();
        }
    }
}

The account implementation of this abstract Repository is:

public class AccountRepository extends Repository<Account> {

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

    public Model<Account> getByEmail(String emailAddress) {...}
}

So far so good, this is all working as expected. But I cannot use a Model<T> as a TModel.

TL;DR

I would like use the following line of code:
AccountModel account = new AccountRepository().getById(1);
Since AccountModel inherits Model<Account> and new AccountRepository().getById() always returns Model<Account> I expect this to work, but it doesn't.

What am I missing?


Show source
| generics   | java   | inheritance   2017-01-04 09:01 0 Answers

Answers ( 0 )

◀ Go back