Moim rozwiązaniem było całkowite uniknięcie interfejsów w obiekcie trwałym. Więc BaseContract
stał się następujący:
public abstract class BaseContract<T extends Code> {
public abstract T getCode();
}
I PersistentContract
został zrealizowany w zakresie konkretnych klas:
public class PersistentContract extends BaseContract<CodeImpl> {
}
Wydaje się, że zapewnia to właściwą równowagę między kodowaniem a interfejsami w klasie bazowej i zaspokajaniem zapotrzebowania Spring Data na konkretne klasy.