Minha solução foi evitar interfaces no objeto persistente. Então
BaseContract
ficou o seguinte:public abstract class BaseContract<T extends Code> {
public abstract T getCode();
}
E
PersistentContract
foi implementado em termos de classes concretas:public class PersistentContract extends BaseContract<CodeImpl> {
}
Isso parece atingir o equilíbrio certo entre a codificação em relação às interfaces na classe base e a satisfação da necessidade do Spring Data de classes concretas.