2009-11-21 28 views
2

好的,这个问题最好用代码解释。因此,我会尽量呈现最简洁的例子。带泛型的休眠组件

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> { } 

我需要为f或者Bar为value.value使用适当的类型转换器,为Foo的每个子类使用不同的转换器。理想情况下,我只想增加此代码,但是我可以将Foo抽象化并将值字段移动到每个具有附加注释的子类。

回答

1

第一种方法是不行的 - 你不能坚持“泛化”类。

您必须将value移动到您建议的具体子类中,或者编写UserType以保留Timestamped组件。

+0

如果我移动值字段,如何设置组件字段的类型。是否存在某种类似于@Type的组件字段? – 2009-11-21 09:01:16

+1

您必须将其声明为具体类型 - 例如'private timestampedValue '并使用'@ AttributeOverrides'。 Hibernate无法处理泛型 - 所有持久化/注解的类都必须显式声明类型参数(或者非泛型)。如果你的层次结构很大,编写自定义的UserType可能是一个更好的方法。 – ChssPly76 2009-11-21 16:30:50

+0

我最终使用ChssPly76的答案。所以foo现在有一个“TimestampedValue 值”字段。 – 2009-11-22 23:24:38

0

如果你想要做的是让许多类对应于许多表,但使用'时间戳'和'值'属性相同的列名,那么你想要的是一个'映射超类'与那些列,而不是嵌入式类。研究@MappedSuperclass注释。

+0

我想我会遇到类似的问题,如果我把田野夷为平地。但我非常想保留它作为一个组件,因为对象上的多个字段可能有时间戳和关联的用户。 – 2009-11-21 09:05:29

+0

您也可以使用映射超类来嵌入。 – Jherico 2009-11-21 23:50:55

0

您正遇到擦除问题。 Hibernate无法知道如何处理泛型类型,因为这些信息在运行时不可用。这将是很好,但。