2015-11-19 72 views
4

我的映射文件(相关数据) - 完整性约束违反:JPA一对多/多对一坚持 - 没有找到父键

家长:

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

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

然后我做in code(pseudo-code):

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

在DAO:

em().persist(attr); 

日志结果表明:

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 (?, ?, ?, ?, ?, ?, ?) 

然后错误:

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

会在解决这个问题感激帮助。我已经尝试了很多事情,但还没有什么...

基础上的意见,嵌入ID的实体映射的问题是:

public class AttributeFunctionalUsageIdVo implements Serializable { 

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

如何界定EmbeddedId类?请提供它以更好地理解关系模型。 AttributeFunctionalUsageIdVo.id。'AttributeFunctionalUsageVo'实体中的attributeId字段对应于'AttributeNameVo'实体的主键? – wypieprz

+0

我在上面的编辑中提供了AttributeFunctionalUsageIdVo类。 是的,它确实对应于AttributeFunctionalUsageVo表中的主键 – Pratik

+0

只是为了澄清不一致:1)实体中没有AttributeListValueAllIdVo - 它应该是“AttributeFunctionalUsageIdVo”而不是? 2)伪代码持久存在'AttributeVo' - 是否应该是'AttributeNameVo'? – wypieprz

回答

2

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

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

JPA 2.0中引入其他的选项,例如允许的关系,以被标记为ID,或甚至指出连接字段maps to the Id字段。然后,您将使用:

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

其中“attributeId”是嵌入ID中映射的名称。那么JPA将设置在embeddedID的属性ID值与AttributeNameVo为您的主键,以及正确处理插入。

+0

我想已经第一件事情是设置(可插入真,可更新=假=)。但是,休眠似乎并不喜欢和服务器无法启动 我INFACT使用JPA 2.0。我会尝试“@ MapsId的解决方案,并在下周报到。 – Pratik

+0

您有2名映射到外地,你应该对他们有一个既插入和更新设置为true,而其他标记为错误的。MapsId是更好的选择,但你应该仍然找出为什么你的服务器不能启动,如果你已经正确设置了映射。 – Chris

+0

我试过使用@MapsId。坚持工作就好,检索生成ID并传播给子实体。然而,在提交我得到的错误:'ORA-00972:标识符太long'插入语句显示为:'插入ATTRIBUTE_FUNCTIONAL_USAGE(DATE_CHANGED,DATE_CREATED,DATE_MODIFIED,USER_CREATED,USER_MODIFIED,** ** id_attributenamevo_ATTRIBUTE_ID,FUNCTIONAL_AREA_CD)值( ?,?,?,?,?,?,?)' 任何帮助? – Pratik

0

好,所以TEMP目的,我已经这样做解决了这个持续,然后刷新以获得具有“id”的父记录。然后我遍历“persisted”记录中的子对象并手动“设置”它是相应的FK。

再次,不是一个完美的解决方案和低效的,但它似乎做的伎俩......我还是感激,如果任何人都可以提出一个更优雅的和更好的解决方案。如果我看到更好的东西,我会接受这个答案!