La mia soluzione era evitare del tutto le interfacce nell'oggetto persistente. Quindi BaseContract
è diventato il seguente:
public abstract class BaseContract<T extends Code> {
public abstract T getCode();
}
E PersistentContract
è stato implementato in termini di classi concrete:
public class PersistentContract extends BaseContract<CodeImpl> {
}
Questo sembra trovare il giusto equilibrio tra la codifica rispetto alle interfacce nella classe base e la soddisfazione del bisogno di Spring Data di classi concrete.