我在创建新对象时有ORA-02291(entitymanager.persist(taskVisit))

@Entity(name = "CRM_TASKDEPARTURE")
@Access(AccessType.PROPERTY)
@DiscriminatorValue(value = TaskType.Consts.VISIT_ID)
public class TaskVisit extends Task {
private static final long serialVersionUID = 1L;

private List<TaskVisitAddress> addresses = new ArrayList();

public TaskVisit() { }


@OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.PERSIST,mappedBy = "taskVisit")
public List<TaskVisitAddress> getAddresses() {
    return addresses;
 }
}


约束是CRM_TaskVisitAddress(TASKID)

实体代码:

@Entity(name = "CRM_TaskDepartureAddress")
public class TaskVisitAddress implements Serializable {
...any fields
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TASKID")
public TaskVisit getTaskVisit() {
    return taskVisit;
 }
@Id
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PERSONADDRESSID")
public PersonAddress getPersonAddress() {
    return personAddress;
}
}


例外:

错误代码:2291
呼叫:INSERT INTO CRM_TASKDEPARTUREADDRESS(TASKID,PERSONADDRESSID)值(?,?)
绑定=> [3299,1]
引起原因:java.sql.SQLIntegrityConstraintViolationException:ORA-02291:违反完整性约束(DUMMY.FK_CRM_TASKDEPARTUREADDR_TASKI)-找不到父键

错误在哪里?
P.s.在测试对象中保存无一例外...

更新
我发现错误的INSERT生成序列
1.插入超类Task(右)
2.插入CRM_TaskDepartureAddress(错误)
3.插入CRM_TASKDEPARTURE(错误)
№2和3必须交换,因为引用到CRM_TASKDEPARTURE的CRM_TaskDepartureAddress。
更新
InheritanceType.JOINED

最佳答案

您不能将ManyToOne作为主键;它表明有许多TaskVisitAddress实例引用同一TaskVisit,而您的@Id需要唯一的东西。

您需要在TaskVisitAddress上找到可以从其他TaskVisitAddress实例中唯一标识的内容,例如通过排序分配的Integer ID。

@JoinColumn(name = "TASKID")在任务表中引用“ TASKID”,因为JPA仅允许关系引用实体的主键,从而使得要求首先插入CRM_TASKDEPARTURE的约束不正确。如果必须保留约束并要求首先插入CRM_TASKDEPARTURE,则可以尝试在joinColumn中指定表名称:

  @JoinColumn(name = "TASKID", referencedColumnName = "CRM_TASKDEPARTURE.TASKID")


如功能要求中所述
https://bugs.eclipse.org/bugs/show_bug.cgi?id=333100

07-28 02:39
查看更多