Min lösning var att undvika gränssnitt alls i det persistenta objektet. Alltså BaseContract
blev följande:
public abstract class BaseContract<T extends Code> {
public abstract T getCode();
}
Och PersistentContract
implementerades i termer av betongklasser:
public class PersistentContract extends BaseContract<CodeImpl> {
}
Detta verkar ha rätt balans mellan kodning mot gränssnitt i basklassen och att tillfredsställa Spring Datas behov av konkreta klasser.