Java 在jpa实体中设置外键时出错:无法刷新非托管对象。。。与非托管对象具有持久关联的

Java 在jpa实体中设置外键时出错:无法刷新非托管对象。。。与非托管对象具有持久关联的,java,jakarta-ee,ejb,jpa-2.0,Java,Jakarta Ee,Ejb,Jpa 2.0,我正在尝试使用JPA2.0设置一些指向静态查找表的外键链接。包含链接和静态查找表的实体分别在类A和状态中定义如下。我还有一个叫做ahistore的实体,它在所有方面都是a的克隆。当我调用logNewA方法时,我从em中找到已经存在的实体状态,创建一个新的a实体,然后创建一个对应的ahistore实体,如下所示。当我尝试这样做时,我得到了这个错误。有人能帮我吗 @Entity @Table(name = "ATABLE") @Inheritance(strategy = InheritanceTy

我正在尝试使用JPA2.0设置一些指向静态查找表的外键链接。包含链接和静态查找表的实体分别在类A和状态中定义如下。我还有一个叫做ahistore的实体,它在所有方面都是a的克隆。当我调用logNewA方法时,我从em中找到已经存在的实体状态,创建一个新的a实体,然后创建一个对应的ahistore实体,如下所示。当我尝试这样做时,我得到了这个错误。有人能帮我吗

@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
@实体
@表(name=“ATABLE”)
@继承(策略=继承类型。每个类的表)
公共类A扩展了BaseBusinessObject{
@身份证
@列(name=“AID”
私人长id;
@JoinColumn(name=“STATUSID”)
@许多酮
私人身份;
//BaseBusinessObject类中的其他无关字段。
}
公共类扩展了BaseBusinessObject{
@身份证
@列(name=“ahistoreid”
私人长id;
@JoinColumn(name=“STATUSID”)
@许多酮
私人身份;
公共故事(状态){
这个状态=状态;
}
//BaseBusinessObject类中的其他无关字段。
}
@实体
@继承(策略=继承类型。每个类的表)
@表(name=“STATUSTABLE”)
公共类状态扩展BaseBusinessType{
@身份证
@列(name=“STATUSID”)
私人长id;
//BaseBusinessType类中的其他不相关字段。
}
@无国籍
@本地豆
公共类somejb{
@持久上下文
实体管理器;
@EJB
处理器bean处理器;
...
公共A logNewA()
抛出系统异常{
Status Status=em.find(//*…NEW-Status*/);//假设现在已连接此文件
A=新A(状态);
返回处理器.saveA(a);
}
}
@无国籍
@本地豆
公共类ProcessorBean{
@持久上下文
实体管理器;
...
public A saveA(A)引发系统异常{
ahistore history=newahistore(a.getStatus());
process.getahistores().add(历史);
返回em.merge(a);
}
}
原因:org.apache.openjpa.persistence.InvalidStateException:在通过字段“au.com.combined.domain.AHistory.Status”级联持久性时遇到生命周期状态为非托管的非托管对象“au.com.combined.domain.Status-1”在刷新期间。但是,此字段不允许级联持久化。不能刷新与非托管对象具有持久关联的非托管对象或图形。
建议的操作:a)将此字段的cascade属性设置为CascadeType.PERSIST或CascadeType.ALL(JPA注释)或“PERSIST”或“ALL”(JPA orm.xml),
b) 启用级联全局持久化,
c) 在刷新之前手动保留相关字段值。
d) 如果引用属于另一个上下文,请通过设置StoreContext.setAllowReferenceToSiblingContext()允许引用它。
失败对象:au.com.combined.domain.Status-1
位于org.apache.openjpa.kernel.SingleFieldManager.preFlushPC(SingleFieldManager.java:775)
位于org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:610)
位于org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:578)
位于org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:494)
位于org.apache.openjpa.kernel.StateManagerImpl.preFlush(StateManagerImpl.java:2971)
位于org.apache.openjpa.kernel.PNewProvisionalState.nonprovisional(PNewProvisionalState.java:45)
位于org.apache.openjpa.kernel.StateManagerImpl.nonprovisional(StateManagerImpl.java:1222)
位于org.apache.openjpa.kernel.SingleFieldManager.preFlushPC(SingleFieldManager.java:812)
位于org.apache.openjpa.kernel.SingleFieldManager.preFlushPCs(SingleFieldManager.java:751)
位于org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:653)
位于org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:578)
位于org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:494)
位于org.apache.openjpa.kernel.StateManagerImpl.preFlush(StateManagerImpl.java:2971)
位于org.apache.openjpa.kernel.PNewState.beforeFlush(PNewState.java:40)
位于org.apache.openjpa.kernel.StateManagerImpl.beforeFlush(StateManagerImpl.java:1047)
位于org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2096)
位于org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2056)
在org.apache.openjpa.kernel.BrokerImpl.beforepletion上(BrokerImpl.java:1974)
在com.ibm.ws.uow.ComponentContextSynchronizationWrapper.before完成之前(ComponentContextSynchronizationWrapper.java:65)
在com.ibm.tx.jta.impl.RegisteredSync.coreDistributeBefore上(RegisteredSync.java:291)
在com.ibm.ws.tx.jta.RegisteredSync.distributeBefore上(RegisteredSync.java:152)
在com.ibm.ws.tx.jta.TransactionImpl.prepreprepare(TransactionImpl.java:2367)
在com.ibm.ws.tx.jta.TransactionImpl.stage1提交处理(TransactionImpl.java:575)
位于com.ibm.tx.jta.impl.TransactionImpl.processCommit(TransactionImpl.java:1015)
... 85多
已解决

问题在于,在saveA函数中(为了保密,我对其进行了解释),我调用了一个Bean,该Bean引用了不同的持久性上下文。在bean的
@PersistenceContext(unitName=“Domain”)EntityManager em
中显式声明unitName之后,问题就出现了

由于另一个实体管理器正在查找状态对象,因此另一个实体管理器(负责实际调用em.merge())没有将该对象识别为托管对象,因此它尝试将其持久化,从而导致错误