how to make openjpa 2.2.0 not persist foreign key

不羁岁月 提交于 2019-12-07 12:19:50

问题


I have two tables.. Asset table

ASSET_ID SYSIBM INTEGER 4 0 No
USER_ID SYSIBM INTEGER 4 0 No
ASSET_TYPE_ID SYSIBM SMALLINT 2 0 No
ACCESSIBILITY_ID SYSIBM SMALLINT 2 0 Yes
DOWNLOAD_TYPE_ID SYSIBM SMALLINT 2 0 No
ASSET_STATUS_ID SYSIBM SMALLINT 2 0 No
ASSET_MARKETING_ID SYSIBM SMALLINT 2 0 Yes
ASSET_PI_SPI_ID SYSIBM SMALLINT 2 0 Yes

and the Accesibility table

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

i have two beans,

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

and Accessibility

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

when the EntitiManager.flush() get's called in my ManagerBean

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

I am getting

javax.ejb.EJBException: See nested exception; nested exception is: org.apache.openjpa.persistence.InvalidStateException: Encountered unmanaged object "com.ibm.tap.ejb.dao.entity.Accessibility@169e3455" in life cycle state unmanaged while cascading persistence via field "com.ibm.tap.ejb.dao.entity.Asset.accessibilityId" during flush. However, this field does not allow cascade persist. You cannot flush unmanaged objects or graphs that have persistent associations to unmanaged objects. Suggested actions: a) Set the cascade attribute for this field to CascadeType.PERSIST or CascadeType.ALL (JPA annotations) or "persist" or "all" (JPA orm.xml), b) enable cascade-persist globally, c) manually persist the related field value prior to flushing. d) if the reference belongs to another context, allow reference to it by setting StoreContext.setAllowReferenceToSiblingContext(). FailedObject: com.ibm.tap.ejb.dao.entity.Accessibility@169e3455

i have tried changing the Asset class to

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

When i do that i get javax.ejb.EJBException: See nested exception; nested exception is: org.apache.openjpa.persistence.EntityExistsException: An object of type "com.ibm.tap.ejb.dao.entity.Accessibility" with oid "1" already exists in this context; another cannot be persisted. FailedObject: com.ibm.tap.ejb.dao.entity.Accessibility@166c27b9

Which make sense to me that i am trying to persist the table i already have. What am i doing wrong?


回答1:


The issue you are having isn't caused by foreign keys. What is happening is that your Asset object contains an Accessibility object that is not being managed by OpenJPA. How to fix this depends on the state of the Accessibility record:

  1. Does the Accessibility record already exist in the database? If so, load it using getEntityManager.find(Accessibility.class, uid) first, and then set it onto your Asset object before you try to persist the Asset object.

  2. If the Accessibility record hasn't already been persisted, then need to persist it first using "getEntityManager.persist(accessibility)" and then set it onto your Asset object before you try to persist it. Or, your other option is to change the cascade type for your accessibility collection to allow persisting, as follows:

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

If you make the cacade change, then any unpersisted Accessibility object on your Asset object will be persisted automatically when you persist the Asset object.



来源:https://stackoverflow.com/questions/11781552/how-to-make-openjpa-2-2-0-not-persist-foreign-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!