Min løsning var overhovedet at undgå grænseflader i det persistente objekt. Altså BaseContract
blev følgende:
public abstract class BaseContract<T extends Code> {
public abstract T getCode();
}
Og PersistentContract
blev implementeret i form af konkrete klasser:
public class PersistentContract extends BaseContract<CodeImpl> {
}
Dette ser ud til at finde den rette balance mellem kodning mod grænseflader i basisklassen og at tilfredsstille Spring Datas behov for konkrete klasser.