Hibernate:如何设置具有相同顺序生成主键的两个表之间的关系?

Hibernate: How to set the relations between two tables with the same sequence generated primary key?

我有 2 个 table,T_PLN 和 T_PLN_CST_PRD 生成器 (M2M.Q_PLN_ID) 在数据库 (Oracle) 中定义,应用作两个 table 的主键。

在保存一个新计划(其中包含一个 CostPeriod)时,我希望生成器为 T_PLN 创建一个新的主键并将其也用作 T_PLN_CST_PRD 中的主键。

Table T_PLN PLN_ID // 序列生成的主键(long) // 更多列

Table T_PLN_CST_PRD PLN_ID // 主键 - 应该与 T_PLN table 中的主键相同 // 更多列

@Entity
@Table(schema = "M2M", name = "T_PLN")
public class Plan {

    @Id
    @SequenceGenerator(name = "m2mPlanId", sequenceName = "M2M.Q_PLN_ID")
    @GeneratedValue(generator = "m2mPlanId")
    @Column(name = "PLN_ID")
    Long id;

    @OneToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "PLN_ID", table = "T_PLN_CST_PRD")
    CostPeriod costPeriod;

    ...   
}



@Entity
@Table(schema = "M2M", name = "T_PLN_CST_PRD")
public class CostPeriod {

    @Id
    @Column(name = "PLN_ID")
    Long planId;

    ...
}

上面的代码缺少连接两个主键的内容,但我不确定是什么...

我尝试了各种关系(@OneToOne 与 mappedBy,@JoinColumn,将 Plan 添加为 T_PLN_CST_PRD 的成员..)但由于种种原因无法正常工作:

和其他人...

还尝试了以下解决方案: OneToOne between two tables with shared primary key 运气不好。

这种关系应该怎么定义?

我认为您缺少双向一对一共享主键模型的 @PrimaryKeyJoinColumnMapsId

你能试试下面的映射吗:

@Entity
@Table(schema = "M2M", name = "T_PLN")
public class Plan {

    @Id
    @SequenceGenerator(name = "m2mPlanId", sequenceName = "M2M.Q_PLN_ID")
    @GeneratedValue(generator = "m2mPlanId")
    @Column(name = "PLN_ID")
    Long id;

    @OneToOne(cascade = {CascadeType.ALL})
    @PrimaryKeyJoinColumn
    //OR
    //Instead of above @OneToOne and @PrimaryKeyJoinColumn use below:
    //@OneToOne(mappedBy="plan", cascade = {CascadeType.ALL})
    CostPeriod costPeriod;

    ...
}



@Entity
@Table(schema = "M2M", name = "T_PLN_CST_PRD")
public class CostPeriod {

    @Id
    @Column(name = "PLN_ID")
    Long planId;

    @OneToOne
    @JoinColumn(name = "id")
    @MapsId
    private Plan plan;  

    ...
}

保存时:

        Plan p = new Plan();
        CostPeriod cp = new CostPeriod();
        p.costPeriod = cp;
        cp.plan = p;
        session.persist(p);

假设 JPA 2+,那么您可以轻松地将其映射如下:

@Entity
@Table(schema = "M2M", name = "T_PLN")
public class Plan {

    @Id
    @SequenceGenerator(name = "m2mPlanId", sequenceName = "M2M.Q_PLN_ID")
    @GeneratedValue(generator = "m2mPlanId")
    @Column(name = "PLN_ID")
    Long id;

    @OneToOne(cascade = {CascadeType.ALL}, mappedBy = "plan")
    CostPeriod costPeriod;
}



@Entity
@Table(schema = "M2M", name = "T_PLN_CST_PRD")
public class CostPeriod {

    @Id
    @OneToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "PLN_ID")
    Plan plan;
}

确保在持久化之前设置了关系的双方。

plan.setCostPeriod(costPeriod);
costPeriod.setPlan(plan);