JPA вполне в состоянии справиться с вашей предложил, потому что общие появляется на уровне абстрактного класса и для ваших конкретных классов имеет точно одно значение для каждого класса. Фактически, JPA будет хранить ваши подклассы в одной или нескольких таблицах в соответствии с выбранной вами структурой @InheritanceStrategy и использует для этого другой механизм.
Вы можете выяснить сами, почему ваш случай не является проблемой, рассуждая о том, как ОРМ может сохранить два класса на БД:
- Вы можете хранить MyStringClass и MyIntegerClass в той же таблице, добавив Столбец дискриминатора, чтобы ORM, когда он загружается из БД, знает, какой конструктор должен быть вызван.
- Вы можете сохранить каждый подкласс в другой таблице.
Что не представляется возможным, с другой стороны, чтобы определить общий
@Entity
@Table(name = "MyGenericClass")
public class MyGenericClass<T> {
private T t;
public MyGenericClass(T t) {
this.t=t;
}
}
Причина этого заключается в том, что во время компиляции, то Т «стирается» из-за типа стирания. Он используется во время компиляции для проверки подписей и правильности типов, но затем он превращается в java.lang.Object внутри JVM. Если вы следуете до сих пор, вы должны быть в состоянии понять следующее:
- В вашем случае, каждый конкретный подкласс AbstractMyClass имеет тип T, который определен для всех экземпляров класса. Хотя информация T не сохраняется в AbstractMyClass, она сохраняется и уникальна внутри подклассов.
- Во втором случае, который я опубликовал, каждый возможный конкретный экземпляр MyGenericClass может иметь различное значение для T, и из-за стирания типа эта информация не сохраняется.
* Примечание: факт, что второй случай не может быть обработан JPA, абсолютно разумен, и если вы попадете в этот случай, вы должны задать себе вопросы о своем дизайне. Generics - отличный инструмент для разработки гибких классов, которые могут обрабатывать другие классы безопасным типом, но безопасный тип - это концепция языка программирования, которая не имеет ничего общего с устойчивостью.
Дополнительно: вы можете использовать javap, чтобы увидеть, что на самом деле является стиранием. Удалите аннотации из MyGenericClass и скомпилируйте их.
G:\>javac MyGenericClass.java
G:\>javap -p MyGenericClass
Compiled from "MyGenericClass.java"
public class MyGenericClass extends java.lang.Object{
private java.lang.Object t;
public MyGenericClass(java.lang.Object);
}
Какую реализацию вы используете? – JMelnik
Hibernate 3.6 с базой данных Oracle 10g. Кроме того, я вручную создаю таблицы вручную. – jaakko
Что вы пытаетесь достичь на уровне дизайна? Какой смысл иметь такой суперкласс? –