Reputation: 8420
I am trying to setup some foreign key links to a static lookup table using JPA 2.0. the entity that contains the link and the static lookup table is defined like this in class A and Status respectively. I also have an entity called AHistory that is a clone of A in all regards. When I call the logNewA method, I find the already existing Entity Status from the em, create a new A entity and then I create a corresponding AHistory entity as seen below. I am getting this error when i try to do this. can any one help me out?
@Entity
@Table(name = "ATABLE")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class A extends BaseBusinessObject {
@Id
@Column(name = "AID"
private long id;
@JoinColumn(name = "STATUSID")
@ManyToOne
private Status status;
// other irrelevant fields in BaseBusinessObject class.
}
public class AHistory extends BaseBusinessObject {
@Id
@Column(name = "AHISTORYID"
private long id;
@JoinColumn(name = "STATUSID")
@ManyToOne
private Status status;
public AHistory(Status status){
this.status = status;
}
// other irrelevant fields in BaseBusinessObject class.
}
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "STATUSTABLE")
public class Status extends BaseBusinessType {
@Id
@Column(name = "STATUSID")
private long id;
// other irrelevant fields in BaseBusinessType class.
}
@Stateless
@LocalBean
public class SomeEJB{
@PersistenceContext
EntityManager em;
@EJB
ProcessorBean processor;
...
public A logNewA()
throws SystemException {
Status status = em.find(/*...NEW-STATUS*/); //assume this is now attached
A a = new A(status);
return processor.saveA(a);
}
}
@Stateless
@LocalBean
public class ProcessorBean {
@PersistenceContext
EntityManager em;
...
public A saveA(A a) throws SystemException {
AHistory history = new AHistory(a.getStatus());
process.getAHistorys().add(history);
return em.merge(a);
}
}
Caused by: <openjpa-2.1.2-SNAPSHOT-r422266:1497841 nonfatal user error> org.apache.openjpa.persistence.InvalidStateException: Encountered unmanaged object "au.com.combined.domain.Status-1" in life cycle state unmanaged while cascading persistence via field "au.com.combined.domain.AHistory.status" 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: au.com.combined.domain.Status-1
at org.apache.openjpa.kernel.SingleFieldManager.preFlushPC(SingleFieldManager.java:775)
at org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:610)
at org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:578)
at org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:494)
at org.apache.openjpa.kernel.StateManagerImpl.preFlush(StateManagerImpl.java:2971)
at org.apache.openjpa.kernel.PNewProvisionalState.nonprovisional(PNewProvisionalState.java:45)
at org.apache.openjpa.kernel.StateManagerImpl.nonprovisional(StateManagerImpl.java:1222)
at org.apache.openjpa.kernel.SingleFieldManager.preFlushPC(SingleFieldManager.java:812)
at org.apache.openjpa.kernel.SingleFieldManager.preFlushPCs(SingleFieldManager.java:751)
at org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:653)
at org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:578)
at org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:494)
at org.apache.openjpa.kernel.StateManagerImpl.preFlush(StateManagerImpl.java:2971)
at org.apache.openjpa.kernel.PNewState.beforeFlush(PNewState.java:40)
at org.apache.openjpa.kernel.StateManagerImpl.beforeFlush(StateManagerImpl.java:1047)
at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2096)
at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2056)
at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1974)
at com.ibm.ws.uow.ComponentContextSynchronizationWrapper.beforeCompletion(ComponentContextSynchronizationWrapper.java:65)
at com.ibm.tx.jta.impl.RegisteredSyncs.coreDistributeBefore(RegisteredSyncs.java:291)
at com.ibm.ws.tx.jta.RegisteredSyncs.distributeBefore(RegisteredSyncs.java:152)
at com.ibm.ws.tx.jta.TransactionImpl.prePrepare(TransactionImpl.java:2367)
at com.ibm.ws.tx.jta.TransactionImpl.stage1CommitProcessing(TransactionImpl.java:575)
at com.ibm.tx.jta.impl.TransactionImpl.processCommit(TransactionImpl.java:1015)
... 85 more
Upvotes: 1
Views: 5865
Reputation: 8420
Solved
The problem was that inside the saveA function (which i paraphrased for secrecy's sake), i was calling a Bean that had a reference to a different persistence context. after explicitly stating the unitName in the @PersistenceContext(unitName = "Domain") EntityManager em
for the bean, the problem dissappeared.
Because the other entity manager was finding the Status object, the different entitymanager (in charge of actually calling em.merge()) did not recognise the object as managed, therefore it attempted to persist it, thus causing the error.
Upvotes: 2