2009-11-21 6 views
2

Хорошо, этот вопрос лучше всего объясняется в коде. Поэтому постараюсь представить самый краткий пример, который я могу.Hibernate Component with Generics

Timestamped.java

@Embeddable 
public class Timestamped<E> { 
    private E value; 
    private Date timestamp; 
    ... 
} 

Foo.java

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="TYPE") 
public class Foo { 
    @Embedded 
    @AttributeOverides({ 
     @AttributeOverride(name="timestamp", [email protected]("VALUE_TS")), 
     @AttributeOverride(name="value",  [email protected]("VALUE")) 
    }) 
    private TimestampedValue<E> value; 
    ... 
} 

Bar.java

@Entity 
@DiscriminatorValue("BAR") 
public class Bar extends Foo<Double> { } 

Что мне нужно е или Bar для использования соответствующего преобразователя типов для value.value и другого преобразователя для каждого подкласса Foo. В идеале я просто хотел бы увеличить этот код, но мне было бы хорошо сделать Foo абстрактным и перемещать поле значений в каждый из подклассов с дополнительными аннотациями.

ответ

1

Первый подход не сработает - вы не можете продолжать «обобщенные» классы.

Вам нужно будет либо переместить value в конкретные подклассы, как вы предложили, либо написать UserType, чтобы сохранить свой компонент Timestamped.

+0

Если я перемещаю поле значения, как установить тип поля компонента. Есть ли какое-то поле компонента над написанием эквивалента @Type? –

+1

Вам придется объявить его конкретным типом - например, 'private TimestampedValue ' и использовать '@ AttributeOverrides'. Hibernate не может иметь дело с генериками - вообще, поэтому все классы, которые вы сохраняете/комментируете, должны явно объявлять параметр типа (или быть не общим). Если иерархия велика, писать пользовательский UserType может быть лучшим подходом. – ChssPly76

+0

Я закончил с помощью ответа ChssPly76. Таким образом, foo теперь имеет поле «TimestampedValue ». –

0

Если вы пытаетесь сделать много классов, соответствующих многим таблицам, но используйте те же имена столбцов для свойств «timestamp» и «value», то то, что вы хотите, - это «сопоставленный суперкласс» с теми, столбцы, а не внедренный класс. Изучите аннотацию @MappedSuperclass.

+0

Я думаю, что столкнулся бы с подобной проблемой, если бы сплющил поля. Но я очень хотел бы сохранить его компонентом, так как несколько полей объекта могут иметь метку времени и связанный с ней пользователь. –

+0

Вы также можете использовать сопоставленные суперклассы для встраиваемых таблиц. – Jherico

0

Вы столкнулись с проблемой стирания. Hibernate не может знать, что делать с родовыми типами, поскольку эта информация недоступна во время выполнения. Было бы неплохо.