我有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 没有运气。
如何定义这种关系?
答案 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;
...
}