如何使OpenJPA的2.2.0不坚持外键(how to make openjpa 2.2.0 no

2019-09-20 16:17发布

我有两个表..资产表

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是

和无障碍环境表

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

我有两个豆,

资产豆

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

当EntitiManager.flush()获取叫我ManagerBean

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

我正进入(状态

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),c)中手动设置此字段以CascadeType.PERSIST或CascadeType.ALL(JPA注释级联属性)或“持续的”或“全部”(JPA orm.xml中)中,b)全局使级联坚持坚持之前冲洗相关的字段值。 d)如果参考属于另一个上下文中,允许通过设置StoreContext.setAllowReferenceToSiblingContext参照它()。 FailedObject:com.ibm.tap.ejb.dao.entity.Accessibility@169e3455

我试图改变资产类

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

当我这样做,我得到javax.ejb.EJBException异常:请参阅嵌套异常; 嵌套的异常是:org.apache.openjpa.persistence.EntityExistsException:类型“com.ibm.tap.ejb.dao.entity.Accessibility”与的一个目的OID“1”已经存在在此上下文中; 另一个不能持续。 FailedObject:com.ibm.tap.ejb.dao.entity.Accessibility@166c27b9

这是有意义的我,我试图坚持表我已经有了。 我究竟做错了什么?

Answer 1:

您遇到的问题不是由外键造成的。 正在发生的事情是,你的资产对象包含没有被OpenJPA的管理的辅助对象。 如何解决这个问题依赖于辅助记录的状态:

  1. 是否可访问记录已在数据库中存在吗? 如果是这样,使用getEntityManager.find(Accessibility.class,UID)首先加载它,然后将其设置到您的资产对象,你尝试坚持资产对象之前。

  2. 如果辅助记录尚未被持久化,那么首先需要坚持使用它“getEntityManager.persist(无障碍)”,然后将它放到你的资产对象尝试坚持它。 或者,你的另一种选择是更改您的辅助功能集合级联型允许持续,具体如下:

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

如果使cacade变化,那么你的资产对象的任何非持久的辅助功能对象时,将自动你坚持下去的资产对象持久化。



文章来源: how to make openjpa 2.2.0 not persist foreign key