【问题标题】:how to make openjpa 2.2.0 not persist foreign key如何使openjpa 2.2.0不保留外键
【发布时间】:2012-07-31 15:58:43
【问题描述】:

我有两张桌子.. 资产表

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;

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

 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) 将此字段的 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 类更改为

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

当我这样做时,我得到 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

这对我来说很有意义,因为我试图保留我已经拥有的表。我究竟做错了什么?

【问题讨论】:

    标签: persistence openjpa


    【解决方案1】:

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

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

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

    @ManyToOne(cascade=cascade={ CascadeType.PERSIST, CascadeType.REMOVE },fetch=FetchType.LAZY) @JoinColumn(name="ACCESSIBILITY_ID") @ForeignKey 私有可访问性accessibilityId;

    如果您进行级联更改,那么当您持久化 Asset 对象时,您的 Asset 对象上的任何未持久化的 Accessibility 对象都将自动持久化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 2012-01-25
      • 2012-05-28
      • 2016-03-19
      相关资源
      最近更新 更多