问题
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:
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.
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