Java 保持继承树的问题

Java 保持继承树的问题,java,hibernate,inheritance,orm,Java,Hibernate,Inheritance,Orm,我在尝试映射继承树时遇到问题。我的模型的简化版本如下所示: @MappedSuperclass @Embeddable public class BaseEmbedded implements Serializable { @Column(name="BE_FIELD") private String beField; // Getters and setters follow } @MappedSuperclass @Embeddable public class De

我在尝试映射继承树时遇到问题。我的模型的简化版本如下所示:

@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的对象,我希望字段是_FIELD、DE_FIELD、ID和type,并保持其值,其余字段为null。如果我持久化一个DerivedClass A类型的对象,我希望这些字段加上FIELD_CLASS_A字段以其值持久化,FIELD FIELD_CLASS_B为空。DerivedClassB类型的对象的等价物

由于
@Embedded
注释仅位于基类,因此Hibernate仅将字段持久化到树中的该级别。我不知道如何告诉Hibernate我希望在树中保持到适当的级别,这取决于嵌入属性的实际类型

我不能在子类中嵌入另一个
@Embedded
属性,因为这将复制已经存在于超类中的数据,并且还会破坏Java模型

我也不能将嵌入属性声明为更具体的类型,因为它仅在运行时创建实际对象,并且层次结构中没有任何分支

有可能解决我的问题吗?还是我应该辞职接受没有办法保持Java模型的现状


任何帮助都将不胜感激。

哇。这是简化版吗?我假设您看到的行为是BaseEmbedded字段被持久化,而不是字段\类\ A或B

问题在于,当Hibernate映射DerivedClassA和B类时,它会将嵌入字段反映并视为BaseEmbedded类。仅仅因为您随后持久化了一个嵌入字段为NestedClass的对象,映射已经完成,并且字段\类\ a和B从未被引用

你需要做的是去掉NestedClass*和embedded字段,而是让fieldClassA和B成为DerivedClassA和B的普通成员。然后在
@实体
中添加一个
名称
字段,我相信这将把它们放在同一个表中。这将允许您进一步折叠/简化类层次结构

见:

@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;

...