首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >JPA onetoMany/ManytoOne持久性完整性约束被违反-找不到父键

JPA onetoMany/ManytoOne持久性完整性约束被违反-找不到父键
EN

Stack Overflow用户
提问于 2015-11-20 05:36:45
回答 2查看 4.2K关注 0票数 4

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

父级:

代码语言:javascript
复制
@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);

孩子:

代码语言:javascript
复制
@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;

然后我使用代码(伪代码):

代码语言:javascript
复制
  AttributeNameVo attr = new AttributeNameVo();
  AttributeFunctionalUsageVo attrFunc = new AttributeFunctionalUsageVo();
  attr.getAttributeFunctionalUsageVos().add(attrFunc);
  attrFunc.setAttributeNameVo(attr);

在DAO中:

代码语言:javascript
复制
  em().persist(attr);

日志结果显示:

代码语言:javascript
复制
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 (?, ?, ?, ?, ?, ?, ?)

然后是错误:

代码语言:javascript
复制
ORA-02291: integrity constraint (ATTR_FUNCTIONAL_USAGE_ATTRB_FK) violated - parent key not found

将非常感谢您在解决此问题方面的帮助。我试过很多方法,但还是没有...

基于注释中的问题,可嵌入id的实体映射是:

代码语言:javascript
复制
public class AttributeFunctionalUsageIdVo implements Serializable {

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

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-21 02:54:50

您的解决方案是必需的,因为您已经将AttributeFunctionalUsageVo中的attributeNameVo映射设置为只读(insertable = false,updatable = false),因此需要JPA检查可嵌入ID中的'attributeId‘字段的其他映射,以设置其值。如果不使用值手动更新该字段,则在执行插入操作时,该字段将为null,这也是导致失败原因。

根据您正在使用的JPA版本,有许多选项。如果您必须使用JPA1.0,您可以修改您的映射,使attributeNameVo是可写的,并且embeddable中的映射是只读的(在两个映射上切换可插入、可更新的设置)。然后,JPA将从关系中拉出'attributeId‘字段,忽略对embeddedid字段的任何更改。这将导致它为null,除非您刷新或以其他方式从数据库重新加载该实体。

JPA2.0引入了其他选项,比如允许将关系标记为ID,甚至声明连接字段maps to the Id字段。然后,您将使用:

代码语言:javascript
复制
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("attributeId")
private AttributeNameVo attributeNameVo;

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

票数 3
EN

Stack Overflow用户

发布于 2015-11-20 06:18:05

好的,出于临时目的,我已经解决了这个问题,我做了一个持久化操作,然后刷新以获取带有"id“的父记录。然后,我循环遍历“持久化”记录中的子对象,并手动“设置”它对应的FK。

再说一次,这不是一个完美的解决方案,效率也很低,但它似乎已经做到了……如果有人能提出一个更优雅更好的解决方案,我将不胜感激。如果我看到了更好的东西,我会接受这个答案!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33814809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档