vendredi 17 mai 2019

Same erasure on for subclass that maps parent method to a different class

I am attempting to refactor a DAO to make it a bit more usable in our code base. We currently have a parameterized AbstractDao that takes in three types:

  1. The database table
  2. The database pojo
  3. A different mapped pojo representation of 2)

So it ends up looking like:

public class AbstractDao<T extends DatabaseTable, R extends DatabaseRecord, M> {
  public AbstractDao(Connection connection, Mapper<R,M> mapper) {
  //save connection and mapper to protected variables
}
public List<M> insert(List<M> records) {
 connection.insertBulk(
   StreamEx.of(records).map(mapper::map).toList()
 );
 }
}

However, this doesn't work on the classic DAO case where we are dealing only with the pojo and the table.

However, there is a common functionality here that can be abstracted into a more basic AbstractDao that is useful across projects. Something like:

AbstractDao<T extends DatabaseTable, R extends Record>

which has a subclass

AbstractMappedDao<T extends DatabaseTable, R extends Record, M> extends AbstractDao<T, R>

The Abstract has a method like:

public List<R> insert(List<R> records) {
  connection.insertBulk(records);
}

and the Mapped should have a method like:

public List<M> insert(List<M> records) {
  super.insert(StreamEx.of(records).map(mapper::map).toList());
}

However, this gives a "same erasure" issue because insert takes in a List of generics.

I have tried abstracting it out into an interface:

public interface Dao<T> {
  public List<T> insert(List<T> records);
}

And making Abstract implement Dao and Mapped implement Dao, but again, same issue.

So my question is how to best approach this problem? This works as expected if I change map's signature to something like:

insertMapped(List<M> mapped);

But I would prefer to keep the contract the same.

Thanks for the help. Looking forward to the discussion!

Aucun commentaire:

Enregistrer un commentaire