Meine Lösung bestand darin, Schnittstellen im persistenten Objekt überhaupt zu vermeiden. Also BaseContract
wurde wie folgt:
public abstract class BaseContract<T extends Code> {
public abstract T getCode();
}
Und PersistentContract
wurde in Form konkreter Klassen implementiert:
public class PersistentContract extends BaseContract<CodeImpl> {
}
Dies scheint das richtige Gleichgewicht zwischen der Codierung für Schnittstellen in der Basisklasse und der Erfüllung des Bedarfs von Spring Data an konkreten Klassen zu finden.