如何使openjpa 2.2.0不能持久保存外键

时间:2012-08-02 16:09:29

标签: persistence openjpa

我有两张桌子.. 资产表

ASSET_ID SYSIBM INTEGER 4 0否
USER_ID SYSIBM INTEGER 4 0否
ASSET_TYPE_ID SYSIBM SMALLINT 2 0否
ACCESSIBILITY_ID SYSIBM SMALLINT 2 0是
DOWNLOAD_TYPE_ID SYSIBM SMALLINT 2 0没有
ASSET_STATUS_ID SYSIBM SMALLINT 2 0没有
ASSET_MARKETING_ID SYSIBM SMALLINT 2 0是
ASSET_PI_SPI_ID SYSIBM SMALLINT 2 0是

和Accesibility表

ACCESSIBILITY_ID SYSIBM SMALLINT 2 0否
ACCESSIBILITY_DESC SYSIBM VARCHAR 50 0否

我有两个豆子,

资产Bean

@Column(name="ASSET_ID")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int assetId;

@Column(name="DATE_CREATED")
private Timestamp dateCreated;

@Column(name="LAST_UPDATED")
private Timestamp lastUpdated;

@Column(name="DATE_PUBLISHED")
private Timestamp datePublished;

@Column(name="ASSET_SURVEY")
private Short assetSurvey;

@Column(name="ASSET_HELP")
private Short assetHelp;

@Column(name="ACCEPTED_TERMS")
private Short acceptedTerms;

@Column(name="ASSET_DESC")
@Lob
private String assetDesc;

@Column(name="ASSET_ALIAS")
private String assetAlias;

@Column(name="ASSET_TITLE")
private String assetTitle;

@Column(name="ASSET_SUMMARY")
private String assetSummary;

@Column(name="ASSET_URL")
private String assetUrl;

@Column(name="ASSET_ORIGINALITY")
private Short assetOriginality; 

@Column(name="ASSET_INVENTION")
private Short invationDisclosure;

@Column(name="ASSET_PRIVACY")
private String  privacyCompliance;  


@ManyToOne
@JoinColumn(name="ASSET_PI_SPI_ID")
private AssetPiSpi assetPiSpiId;

@ManyToOne
@JoinColumn(name="ASSET_MARKETING_ID")
@ForeignKey
private AssetMarketing assetMarketingId;    

@ManyToOne(cascade=CascadeType.REMOVE,fetch=FetchType.LAZY)
@JoinColumn(name="ACCESSIBILITY_ID")
@ForeignKey
private Accessibility accessibilityId;

@Column(name="ASSET_ID") @GeneratedValue(strategy=GenerationType.IDENTITY) private int assetId; @Column(name="DATE_CREATED") private Timestamp dateCreated; @Column(name="LAST_UPDATED") private Timestamp lastUpdated; @Column(name="DATE_PUBLISHED") private Timestamp datePublished; @Column(name="ASSET_SURVEY") private Short assetSurvey; @Column(name="ASSET_HELP") private Short assetHelp; @Column(name="ACCEPTED_TERMS") private Short acceptedTerms; @Column(name="ASSET_DESC") @Lob private String assetDesc; @Column(name="ASSET_ALIAS") private String assetAlias; @Column(name="ASSET_TITLE") private String assetTitle; @Column(name="ASSET_SUMMARY") private String assetSummary; @Column(name="ASSET_URL") private String assetUrl; @Column(name="ASSET_ORIGINALITY") private Short assetOriginality; @Column(name="ASSET_INVENTION") private Short invationDisclosure; @Column(name="ASSET_PRIVACY") private String privacyCompliance; @ManyToOne @JoinColumn(name="ASSET_PI_SPI_ID") private AssetPiSpi assetPiSpiId; @ManyToOne @JoinColumn(name="ASSET_MARKETING_ID") @ForeignKey private AssetMarketing assetMarketingId; @ManyToOne(cascade=CascadeType.REMOVE,fetch=FetchType.LAZY) @JoinColumn(name="ACCESSIBILITY_ID") @ForeignKey private Accessibility accessibilityId;

和辅助功能

在我的ManagerBean中调用EntitiManager.flush()时

@Column(name="ACCESSIBILITY_ID")
private short accessibilityId;

@Column(name="ACCESSIBILITY_DESC")
private String accessibilityDesc;

@OneToMany(mappedBy="accessibilityId",cascade=CascadeType.REMOVE,fetch=FetchType.LAZY)  
private Set<Asset> assetCollection;

我正在

javax.ejb.EJBException:请参阅嵌套异常;嵌套异常是:org.apache.openjpa.persistence.InvalidStateException:在生命周期状态下遇到非托管对象“com.ibm.tap.ejb.dao.entity.Accessibility@169e3455”,而在通过字段“com.ibm.tap”级联持久性时不受管理.ejb.dao.entity.Asset.accessibilityId“在冲洗期间。但是,此字段不允许级联持续存在。您无法刷新与非托管对象具有持久关联的非托管对象或图形。建议的操作:a)将此字段的cascade属性设置为CascadeType.PERSIST或CascadeType.ALL(JPA注释)或“persist”或“all”(JPA orm.xml),b)全局启用cascade-persist,c)手动在冲洗之前保持相关的字段值。 d)如果引用属于另一个上下文,则允许通过设置StoreContext.setAllowReferenceToSiblingContext()来引用它。 FailedObject:com.ibm.tap.ejb.dao.entity.Accessibility@169e3455

我尝试将Asset类更改为

 em.persist(asset);  
 em.flush();

当我这样做时,我得到了     javax.ejb.EJBException:参见嵌套异常;嵌套异常是:org.apache.openjpa.persistence.EntityExistsException:在此上下文中已存在具有oid“1”的“com.ibm.tap.ejb.dao.entity.Accessibility”类型的对象;另一个不能坚持下去。 FailedObject:com.ibm.tap.ejb.dao.entity.Accessibility@166c27b9

对我而言,我正试图坚持我已经拥有的桌子。我究竟做错了什么?

1 个答案:

答案 0 :(得分:5)

您遇到的问题不是由外键引起的。发生的事情是您的Asset对象包含一个不受OpenJPA管理的Accessibility对象。如何解决这个问题取决于辅助功能记录的状态:

  1. 数据库中是否已存在辅助功能记录?如果是这样,首先使用getEntityManager.find(Accessibility.class,uid)加载它,然后在尝试保留Asset对象之前将其设置到Asset对象上。

  2. 如果尚未保留辅助功能记录,则需要先使用“getEntityManager.persist(accessibility)”将其保留,然后在尝试保留之前将其设置到Asset对象上。或者,您的另一个选择是更改辅助功能集合的级联类型以允许持久化,如下所示:

  3. @ManyToOne(cascade=cascade={ CascadeType.PERSIST, CascadeType.REMOVE },fetch=FetchType.LAZY)
    @JoinColumn(name="ACCESSIBILITY_ID")
    @ForeignKey
    private Accessibility accessibilityId;
    

    如果进行cacade更改,则在保留Asset对象时,Asset对象上的任何未加载的Accessibility对象都将自动保留。