JPA onetoMany / ManytoOne坚持 - 违反了完整性约束 - 找不到父键 [英] JPA onetoMany/ManytoOne persist - integrity constraint violated - parent key not found

查看:140
本文介绍了JPA onetoMany / ManytoOne坚持 - 违反了完整性约束 - 找不到父键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的映射文件(相关数据):

家长:

  @Entity 
@Table(name =ATTRIBUTE_NAME,uniqueConstraints = @UniqueConstraint(columnNames =NAME_TEXT))
@SequenceGenerator(name =ATTRIBUTE_NAME_SEQ,sequenceName =ATTRIBUTE_NAME_SEQ,initialValue = 1,allocationSize = 1)
public class AttributeNameVo implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator =ATTRIBUTE_NAME_SEQ)
@ Column(name =ATTRIBUTE_ID,unique = true,nullable = false,precision = 6,scale = 0)
private int attributeId;

@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy =attributeNameVo)
private Set< AttributeFunctionalUsageVo> attributeFunctionalUsageVos = new HashSet< AttributeFunctionalUsageVo>(0);

孩子:

  @Entity 
@Table(name =ATTRIBUTE_FUNCTIONAL_USAGE)
public class AttributeFunctionalUsageVo implements Serializable {

@EmbeddedId
@AttributeOverrides({@ AttributeOverride (name =attributeId,column = @Column(name =ATTRIBUTE_ID,nullable = false,precision = 6,scale = 0)),
@AttributeOverride(name =functionalAreaCd,column = @Column name =FUNCTIONAL_AREA_CD,nullable = false,length = 5))})
private AttributeFunctionalUsageIdVo id;
$ b @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =attributeId,referencedColumnName =ATTRIBUTE_ID,nullable = true,insertable = false,updatable = false)
private AttributeNameVo attributeNameVo;

然后我在代码中执行代码(伪代码):

  AttributeNameVo attr = new AttributeNameVo(); 
AttributeFunctionalUsageVo attrFunc = new AttributeFunctionalUsageVo();
attr.getAttributeFunctionalUsageVos()。add(attrFunc);
attrFunc.setAttributeNameVo(attr);

在DAO中:

  em()。persist(attr); 

日志结果显示:

<$ p $ (ACTIVE_FL,DATE_CREATED,DATE_MODIFIED,DISPLAY_SEQ_NO,EXTERNAL_REF_ID,HINT_TEXT,LOV_FL,MAX_LENGTH,MAX_RANGE,MIN_RANGE,NAME_TEXT,POS_FL等),从

中选择ATTRIBUTE_NAME_SEQ.nextval。 PUBLIC_FL,RAPID_SEARCH_FL,REQUIRED_FL,TYPE_CD,USER_CREATED,USER_MODIFIED,ATTRIBUTE_ID)值(,,,,,,,,,,,,,,,,,,,,,,,,,, (?,?,?,?,?,?)
插入到ATTRIBUTE_FUNCTIONAL_USAGE(DATE_CHANGED,DATE_CREATED,DATE_MODIFIED,USER_CREATED,USER_MODIFIED,ATTRIBUTE_ID,FUNCTIONAL_AREA_CD)

然后错误:

  ORA-02291:违反了完整性约束(ATTR_FUNCTIONAL_USAGE_ATTRB_FK) - 找不到父键

帮助解决这个问题。我已经尝试了很多东西,但还没有......



基于评论中的问题,嵌入ID的实体映射为:

  public class AttributeFunctionalUsageIdVo implements Serializable {

@Column(name =ATTRIBUTE_ID,nullable = false,precision = 6,scale = 0 )
private int attributeId;


解决方案

您的解决方案是必需的,因为您已将attributeNameVo映射在AttributeFunctionalUsageVo内为只读(insertable = false,updatable = false),因此JPA需要检查嵌入ID中'attributeId'字段的其他映射以设置其值。如果您没有使用值手动更新该字段,则在插入发生时该字段为空,并且是导致失败的原因。

取决于您使用的是哪个JPA版本,有很多选项。如果您必须使用JPA 1.0,则可以修改映射,以使attributeNameVo可写,并且可嵌入的映射是只读的(在两个映射中切换可插入的可更新设置)。然后,JPA将从关系中提取'attributeId'字段,忽略对嵌入ID字段的任何更改。这将导致它为空,除非您刷新或以其他方式从数据库重新加载实体。



JPA 2.0引入了其他选项,例如允许关系标记为ID,甚至声明连接字段映射到Id 字段。然后你可以使用:

$ $ p $ $ $ $ $ $ $
private AttributeNameVo attributeNameVo;

其中attributeId是Embedded ID中映射的名称。然后,JPA将使用AttributeNameVo的主键为您设置embeddedID中的attributeId值,并正确处理插入。


My mapping files (relevant data):

Parent:

@Entity
@Table(name = "ATTRIBUTE_NAME", uniqueConstraints = @UniqueConstraint(columnNames = "NAME_TEXT"))
@SequenceGenerator(name="ATTRIBUTE_NAME_SEQ",    sequenceName="ATTRIBUTE_NAME_SEQ", initialValue = 1, allocationSize = 1)
public class AttributeNameVo implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,    generator="ATTRIBUTE_NAME_SEQ")
    @Column(name = "ATTRIBUTE_ID", unique = true, nullable = false, precision = 6, scale = 0)
    private int attributeId;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "attributeNameVo")
    private Set<AttributeFunctionalUsageVo> attributeFunctionalUsageVos = new HashSet<AttributeFunctionalUsageVo>(0);

Child:

@Entity
@Table(name = "ATTRIBUTE_FUNCTIONAL_USAGE")
public class AttributeFunctionalUsageVo implements Serializable {

        @EmbeddedId
        @AttributeOverrides({@AttributeOverride(name = "attributeId", column = @Column(name = "ATTRIBUTE_ID", nullable = false, precision = 6, scale = 0) ),
                             @AttributeOverride(name = "functionalAreaCd", column = @Column(name = "FUNCTIONAL_AREA_CD", nullable = false, length = 5) ) })
        private AttributeFunctionalUsageIdVo id;

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "attributeId", referencedColumnName="ATTRIBUTE_ID", nullable = true, insertable = false, updatable = false)
        private AttributeNameVo attributeNameVo;

Then I do in code (pseudo-code):

  AttributeNameVo attr = new AttributeNameVo();
  AttributeFunctionalUsageVo attrFunc = new AttributeFunctionalUsageVo();
  attr.getAttributeFunctionalUsageVos().add(attrFunc);
  attrFunc.setAttributeNameVo(attr);

In the DAO:

  em().persist(attr);

The log result shows:

select ATTRIBUTE_NAME_SEQ.nextval from dual

insert into ATTRIBUTE_NAME (ACTIVE_FL, DATE_CREATED, DATE_MODIFIED,  DISPLAY_SEQ_NO, EXTERNAL_REF_ID, HINT_TEXT, LOV_FL, MAX_LENGTH, MAX_RANGE, MIN_RANGE, NAME_TEXT, POS_FL, PUBLIC_FL, RAPID_SEARCH_FL, REQUIRED_FL, TYPE_CD, USER_CREATED, USER_MODIFIED, ATTRIBUTE_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

insert into ATTRIBUTE_FUNCTIONAL_USAGE (DATE_CHANGED, DATE_CREATED, DATE_MODIFIED, USER_CREATED, USER_MODIFIED, ATTRIBUTE_ID, FUNCTIONAL_AREA_CD) values (?, ?, ?, ?, ?, ?, ?)

And then the error:

ORA-02291: integrity constraint (ATTR_FUNCTIONAL_USAGE_ATTRB_FK) violated - parent key not found

Would appreciate help in fixing this issue. I have tried many things, but yet nothing ...

Based on the question in the comment the entity mapping for embeddable id is:

public class AttributeFunctionalUsageIdVo implements Serializable {

@Column(name = "ATTRIBUTE_ID", nullable = false, precision = 6, scale = 0)
private int attributeId;

解决方案

Your solution is required because you have made the attributeNameVo mapping within AttributeFunctionalUsageVo as read only (insertable = false, updatable = false), so JPA is required to check the other mapping for the 'attributeId' field within your embeddable ID to set its value. If you don't update that field manually with a value, it is null when the insert happens, and is why you get the failure.

There are a number of options depending on which JPA version you are working with. If you must use JPA 1.0, you can modify your mappings so that attributeNameVo is writable and the mapping in the embeddable has is read only, (switch the insertable, updatable settings on the two mappings). JPA will then pull the 'attributeId' field from the relationship, ignoring any changes to the embeddedid id field. This will result in it being null unless you refresh or otherwise reload the entity from the database though.

JPA 2.0 introduced other options, such as allowing relationships to be marked as the ID, or even stating that the join field maps to the Id field. You would then use:

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("attributeId")
private AttributeNameVo attributeNameVo;

Where the "attributeId" is the name of the mapping within the Embedded ID. JPA will then set the attributeId value in the embeddedID with the primary key of the AttributeNameVo for you, as well as handle the inserts correctly.

这篇关于JPA onetoMany / ManytoOne坚持 - 违反了完整性约束 - 找不到父键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆