我在尝试映射继承树时遇到问题。我的模型的简化版本是这样的:
@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和TYPE保持其值,其余字段为null。如果我持久化DerivedClass类型的对象,我希望这些相同的字段加上FIELD_CLASS_A字段与它们的值和字段FIELD_CLASS_B保持为空。类似于DerivedClassB类型的对象的东西。
由于@Embedded
注释仅在BaseClass中,因此Hibernate仅将字段持久保存到树中的该级别。我不知道如何告诉Hibernate我希望在树中保持适当的级别,具体取决于嵌入属性的实际类型。
我不能在子类中拥有另一个@Embedded
属性,因为这会复制已存在于超类中的数据,并且还会破坏Java模型。
我也不能将嵌入属性声明为更具体的类型,因为它仅在运行时创建实际对象并且在层次结构中没有单个分支。
有可能解决我的问题吗?或者我是否应该辞职以接受无法保持Java模型的原因?
非常感谢任何帮助。
答案 0 :(得分:0)
哇。这是简化版本?我假设你看到的行为是BaseEmbedded字段是持久的,但不是FIELD_CLASS_A或B?
问题在于,当Hibernate映射DerivedClassA和B类时,它反映并将嵌入字段视为BaseEmbedded类。只是因为你然后持有一个嵌入字段为NestedClass的对象,映射已经完成,而且FIELD_CLASS_A和B从未被引用。
您需要做的是摆脱NestedClass *和嵌入字段,而将fieldClassA和B作为DerivedClassA和B的普通成员。然后添加name
字段到{{1}我相信这会把它们放在同一张桌子上。这将允许您进一步折叠/简化类层次结构。
请参阅:http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#d0e1168
@Entity