Hibernate:如何使用相同的序列生成主键设置两个表之间的关系?

时间:2016-02-15 15:34:30

标签: hibernate jpa primary-key sequence

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

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

表T_PLN PLN_ID //序列生成的主键(长) //更多列

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

@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 with mappedBy,@ JoinColumn,将Plan添加为T_PLN_CST_PRD的成员..)但由于各种原因无法使其工作:

  • IdentifierGenerationException:在调用save()之前必须手动分配此类的ID:

  • IdentifierGenerationException:尝试从null一对一属性中分配id

和其他人......

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

如何定义这种关系?

2 个答案:

答案 0 :(得分:1)

假设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);

答案 1 :(得分:0)

对于双向一对一共享主键模型,我认为您缺少In the finally block of the script. Receiving the output from the job: In the try block of the job. In the finally block of the job. @PrimaryKeyJoinColumn

您可以尝试以下映射:

MapsId

保存时:

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

    ...
}