Hibernate / JPA 2.0 - 每个类的表和@EmbeddedId继承

时间:2013-05-17 10:08:54

标签: hibernate inheritance jpa-2.0 hibernate-mapping

意识到我不支持Hibernate中的@Embeddable组件继承,我正在尝试找到处理我的自定义实体映射的最佳策略。

故事如下:

  • 我有两张表:prices_a_bprices_a_b_c

  • 我有两个实体映射到每个实体:PriceABPriceABC

  • 这两个表都只有prices_a_b_c为PK添加额外列的复合PK

因此,这将是程序化翻译:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Price implements Serializable {
  @EmbeddedId
  private AbstractPricePk id;

  public AbstractPricePk getId() {
      return id;
  }
}

@Entity
@Table(name = "price_a_b")
@AssociationOverrides(
  { 
    @AssociationOverride(name = "id.a", joinColumns = @JoinColumn(name = "a")),
    @AssociationOverride(name = "id.b", joinColumns = @JoinColumn(name = "b"))
  }
)
public class PriceAB extends Price {
  private PriceABPk id;

  protected PriceAB() {}

  public PriceAB(PriceABPk id) {
    this.id = id;
  }

  @Override
  @EmbeddedId
  public PriceABPk getId() {
    return id;
  }
}

@Entity
@Table(name = "price_a_b_c")
@AssociationOverrides(
    { 
        @AssociationOverride(name = "id.a", joinColumns = @JoinColumn(name = "a")),
        @AssociationOverride(name = "id.b", joinColumns = @JoinColumn(name = "b")),
        @AssociationOverride(name = "id.c", joinColumns = @JoinColumn(name = "c"))
    }
)
public class PriceABC extends Price {
    private PriceABCPk id;

    protected PriceABC() {}

    public PriceABC(PriceABCPk id) {
        this.id = id;
    }

    @Override
    @EmbeddedId
    public PriceABCPk getId() {
      return id;
    }
}

以下是PKs模型:

public interface PricePk extends Serializable {
    public A getA();
    public B getB();
}

@MappedSuperclass
public abstract class AbstractPricePk implements PricePK {
    @ManyToOne
    @JoinColumn(name = "a")
    private A a;

    @ManyToOne
    @JoinColumn(name = "b")
    private B b;

    protected AbstractPricePK() { }

    public AbstractPricePK(A a, B b) {
        this.a = a;
        this.b = b;
    }

    public A getA() {
        return this.a; 
    }

    public void setA(A a) {
        this.a = a;
    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }
}

@Embeddable
public class PriceABPk extends AbstractPricePk {

    public PriceABk(A a, B b) {
        super(a,b);
    }
}

@Embeddable
public class PriceABCPk extends AbstractPricePk {
    @ManyToOne
    private C c;

    public PriceABCPk(A a, B b, C c) {
        super(a, b);
        this.c = c;
    }

    public C getC() {
        return b;  
    }

    public void setC(C c) {
        this.c = c;
    }
}

我得到的错误:

org.hibernate.AnnotationException: PriceABPk must not have @Id properties when used as an @EmbeddedId: PriceAB.id

现在,所有这一切背后的想法是我希望有一个PriceService可以查询两个表并返回一个Price对象。稍后,如果我需要从C检索PriceABC,我可以执行instanceof,但大多数情况下我需要对Price这两种类型执行相同的操作对象。同样,我希望有PriceDao创建Price个对象,具体取决于我作为参数传递的对象。

你们认为哪种策略最合适?

提前致谢!

1 个答案:

答案 0 :(得分:0)

你可以通过用@EmbeddedId

中的组合替换继承来制作'hack'
@Table (name="prices_a_b")
public class PriceAB extends Price {

    @EmbeddedId
    private PriceABId id;

    // getters/setters etc.
}

@Table (name="prices_a_b_c")
public class PriceABC extends Price {   
    @EmbeddedId
    private PriceABCId id;

    @Embeddable 
    class PriceABCId implements Serializable {
            private PriceABId id;

            @Column(name="COLUMN_C")
            private C additionalPkPropertyC;
    }
}

@MappedSuperclass
public abstract class Price {
    //all common properties go here
}