我的映射文件(相关数据):
父级:
@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;
然后我使用代码(伪代码):
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;
发布于 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字段。然后,您将使用:
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("attributeId")
private AttributeNameVo attributeNameVo;
其中" attributeId“是嵌入ID中映射的名称。然后,JPA将使用embeddedID的主键设置AttributeNameVo中的JPA值,并正确处理插入。
发布于 2015-11-20 06:18:05
好的,出于临时目的,我已经解决了这个问题,我做了一个持久化操作,然后刷新以获取带有"id“的父记录。然后,我循环遍历“持久化”记录中的子对象,并手动“设置”它对应的FK。
再说一次,这不是一个完美的解决方案,效率也很低,但它似乎已经做到了……如果有人能提出一个更优雅更好的解决方案,我将不胜感激。如果我看到了更好的东西,我会接受这个答案!
https://stackoverflow.com/questions/33814809
复制相似问题