我在映射继承树时遇到了问题。我的模型的简化版本如下:
@MappedSuperclass
@Embeddable
public class BaseEmbedded implements Serializable {
@Column(name="BE_FIELD")
private String beField;
// Getters and setters follow
}
@MappedSuperclass
@Embeddable
public class DerivedEmbedded extends BaseEmbedded {
@Column(name="DE_FIELD")
private String deField;
// Getters and setters follow
}
@MappedSuperclass
public abstract class BaseClass implements Serializable {
@Embedded
protected BaseEmbedded embedded;
public BaseClass() {
this.embedded = new BaseEmbedded();
}
// Getters and setters follow
}
@Entity
@Table(name="MYTABLE")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING)
public class DerivedClass extends BaseClass {
@Id
@Column(name="ID", nullable=false)
private Long id;
@Column(name="TYPE", nullable=false, insertable=false, updatable=false)
private String type;
public DerivedClass() {
this.embedded = new DerivedClass();
}
// Getters and setters follow
}
@Entity
@DiscriminatorValue("A")
public class DerivedClassA extends DerivedClass {
@Embeddable
public static NestedClassA extends DerivedEmbedded {
@Column(name="FIELD_CLASS_A")
private String fieldClassA;
}
public DerivedClassA() {
this.embedded = new NestedClassA();
}
// Getters and setters follow
}
@Entity
@DiscriminatorValue("B")
public class DerivedClassB extends DerivedClass {
@Embeddable
public static NestedClassB extends DerivedEmbedded {
@Column(name="FIELD_CLASS_B")
private String fieldClassB;
}
public DerivedClassB() {
this.embedded = new NestedClassB();
}
// Getters and setters follow
}在Java级别,这个模型运行得很好,我认为是合适的。当要持久化一个对象时,我的问题就出现了。
在运行时,我可以创建一个对象,它可以是DerivedClass、DerivedClassA或DerivedClassB的实例。正如您所看到的,每个派生类都引入了一个仅对特定派生类有意义的新字段。所有类在数据库中共享相同的物理表。如果我持久化一个类型为DerivedClass的对象,我希望字段BE_FIELD、DE_FIELD、ID和类型与它们的值一起持久化,其余字段为null。如果我持久化类型为DerivedClass A的对象,我希望这些字段加上FIELD_CLASS_A字段与它们的值一起持久化,字段FIELD_CLASS_B为null。与DerivedClassB类型的对象等效的东西。
由于@Embedded注释仅位于BaseClass上,Hibernate只将字段持久化到树中的那个级别。我不知道如何告诉Hibernate,我想要持久化到树中的适当级别,这取决于嵌入式属性的实际类型。
子类中不能有另一个@Embedded属性,因为这会重复已经存在于超类中的数据,并且还会破坏Java模型。
我也不能将嵌入的属性声明为更特定的类型,因为它只在运行时创建了实际的对象,并且在层次结构中没有一个分支。
有可能解决我的问题吗?或者,我是否应该辞职,接受没有办法将Java模型持久化呢?
任何帮助都将不胜感激。
发布于 2010-06-02 20:29:40
哇。这是简化的版本吗?我假设您所看到的行为是BaseEmbedded字段是持久化的,而不是FIELD_CLASS_A或B?
问题是,当Hibernate映射DerivedClassA和B类时,它会将嵌入的字段映射为BaseEmbedded类。仅仅因为您随后持久化了一个具有嵌入字段为NestedClass的对象,映射就已经完成,FIELD_CLASS_A和B永远不会被引用。
您需要做的是去掉NestedClass*和embedded字段,让fieldClassA和B成为DerivedClassA和B的普通成员,然后向@Entity中添加一个name字段,这将把它们放在相同的表中。这将允许您进一步折叠/简化类层次结构。
请参阅:http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#d0e1168
@Entity(name = "DerivedClass")
@DiscriminatorValue("A")
public class DerivedClassA extends DerivedClass {
@Column(name="FIELD_CLASS_A")
private String fieldClassA;
...
@Entity(name = "DerivedClass")
@DiscriminatorValue("B")
public class DerivedClassB extends DerivedClass {
@Column(name="FIELD_CLASS_B")
private String fieldClassB;
...https://stackoverflow.com/questions/2813306
复制相似问题