0

尝试保留新实体时遇到问题。我使用 Eclipselink 2.4.2 作为实体管理器。store 方法中的我的 BaseDao 类在将实体持久化为新实体后刷新和刷新它(persist->flush->refresh)。一切都发生在一个事务中。

我的实体看起来像这样(我关心的部分):

TrustEntity {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "trust", cascade = {CascadeType.ALL})
    @PrivateOwned
    private List<TrustIncentiveRateEntity> trustIncentiveRates;
}

TrustIncentiveRateEntity {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TRUST_ID", nullable = false)
    private TrustEntity trust;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "trustIncentiveRate", cascade = {CascadeType.ALL})
    @PrivateOwned
    private List<TrustIncentiveRateValueEntity> trustIncentiveRateValues;
}

TrustIncentiveRateValueEntity {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TRUST_INCENTIVE_RATE_ID", nullable = false)
    private TrustIncentiveRateEntity trustIncentiveRate;
}

我正在创建一个新的 Trust 实体,实例化一个 TrustIncentiveRateEntity 列表,在其中创建一个新元素,实例化一个 TrustIncentiveRateEntity 并在其中创建一个新元素。在调试期间,我可以看到所有引用,在这两种方式中,都是正确的。

现在,当我尝试坚持这一点时,会发生以下情况:

从服务器登录:

FINE: SELECT SEQ_TRUST.NEXTVAL FROM DUAL

FINE: SELECT SEQ_TRUST_INCENTIVE_RATE.NEXTVAL FROM DUAL

FINE: SELECT SEQ_TRUST_INCENTIVE_RATE_VALUE.NEXTVAL FROM DUAL

FINE: INSERT INTO TRUST (TRUST_ID, ACTION_DATE, ACTION_USER_ID, IS_ACTIVE, CREATION_DATE, CREATION_USER_ID, IS_INCENTIVE_ACTIVE, IS_NO_CREDIT_LIMIT, PROCESS_CURRENT_STATUS, REMARKS, STATUS_INCENTIVE, TRUST_CODE, TRUST_NAME, TRUST_TYPE, UPDATE_DATE, UPDATE_USER_ID, VERSION_OPT_LOCK, STRUCTURAL_ORG_UNIT_SALES_ID, STRUCTURAL_ORG_UNIT_ID, USER_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    bind => [38007, 2013-04-26 09:46:31.582, 1003186, true, 2013-04-26 07:46:34.659, 1003186, true, false, OPEN, null, OPEN, 100058, 741963852, T, null, null, 1, 387, 387, 1003186]

FINE: INSERT INTO TRUST_INCENTIVE_RATE (TRUST_INCENTIVE_RATE_ID, CREATION_DATE, CREATION_USER_ID, EQUIPMENT_SIZE, EXTENDED_EQ_GROUP_ID, RATE_BASIS, UPDATE_DATE, UPDATE_USER_ID, VERSION_OPT_LOCK, TRADE_ID, TRUST_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    bind => [15001, 2013-04-26 07:46:39.862, 1003186, 20, 2, B, null, null, 1, 144001, 38007]

FINE: INSERT INTO TRUST_INCENTIVE_RATE_VALUE (TRUST_INCENTIVE_RATE_VALUE_ID, CREATION_DATE, CREATION_USER_ID, EFFECTIVE_DATE, EXPIRY_DATE, INCENTIVE, STATUS, UPDATE_DATE, UPDATE_USER_ID, VERSION_OPT_LOCK, CURRENCY_CODE, TRUST_INCENTIVE_RATE_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    bind => [14007, 2013-04-26 07:46:39.955, 1003186, 2013-04-26 00:00:00.0, 9999-12-31 00:00:00.0, 12, OPEN, null, null, 1, USD, 15001]

FINE: SELECT TRUST_ID, ACTION_DATE, ACTION_USER_ID, IS_ACTIVE, CREATION_DATE, CREATION_USER_ID, IS_INCENTIVE_ACTIVE, IS_NO_CREDIT_LIMIT, PROCESS_CURRENT_STATUS, REMARKS, STATUS_INCENTIVE, TRUST_CODE, TRUST_NAME, TRUST_TYPE, UPDATE_DATE, UPDATE_USER_ID, VERSION_OPT_LOCK, STRUCTURAL_ORG_UNIT_SALES_ID, STRUCTURAL_ORG_UNIT_ID, USER_ID FROM TRUST WHERE (TRUST_ID = ?)
    bind => [38007]

FINE: SELECT TRUST_INCENTIVE_RATE_ID, CREATION_DATE, CREATION_USER_ID, EQUIPMENT_SIZE, EXTENDED_EQ_GROUP_ID, RATE_BASIS, UPDATE_DATE, UPDATE_USER_ID, VERSION_OPT_LOCK, TRADE_ID, TRUST_ID FROM TRUST_INCENTIVE_RATE WHERE (TRUST_ID = ?)
    bind => [38007]

FINE: SELECT TRUST_INCENTIVE_RATE_VALUE_ID, CREATION_DATE, CREATION_USER_ID, EFFECTIVE_DATE, EXPIRY_DATE, INCENTIVE, STATUS, UPDATE_DATE, UPDATE_USER_ID, VERSION_OPT_LOCK, CURRENCY_CODE, TRUST_INCENTIVE_RATE_ID FROM TRUST_INCENTIVE_RATE_VALUE WHERE (TRUST_INCENTIVE_RATE_ID = ?)
    bind => [15001]

到目前为止一切顺利,但是当事务由 EntityManager 提交时,我得到以下异常:

WARNING: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: my.package.entity.TrustIncentiveRateEntity@1fa1df7.
 at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects(RepeatableWriteUnitOfWork.java:303)
 at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:706)
 at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1498)
 at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3151)
 at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:345)
 at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:158)
 at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68)
 at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:435)
 at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:855)
 at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5136)
 at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901)
 at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045)
 at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
 at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
 at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
 at $Proxy241.save(Unknown Source)

这对我来说似乎很奇怪,就像 EM 试图在 TrustIncentiveRateEntity 之前实际存储 TrustIncentiveRateValueEntity 并且看不到 TrustIncentiveRateEntity。在查看了类似的线程后,我将 CascadeType.PERSIST 添加到了 TrustIncentiveRateValueEntity 类中 trustIncentiveRate 字段的 @ManyToOne 注释中。之后情况看起来像这样:EM 像之前一样插入实体,然后它从 SEQ_TRUST_INCENTIVE_RATE 获取 nextval 并尝试再次插入 TrustIncentiveRateValueEntity(使用新 id,但其余字段值保持不变)。它会导致违反约束,因为我对某些表列的横截面有独特的约束。异常,交易回滚,我还是很难过。

我在 BaseDao 类中的 store 方法:

@TransactionAttribute(TransactionAttributeType.MANDATORY)
public T_ENTITY store(T_ENTITY entity) {
    if (!entity.isNewlyCreated()) {
        T_ENTITY mergedEntity = em.merge(entity);
        flush();
        return mergedEntity;
    } else {
        try {
            em.persist(entity);
            flush();
            refresh();
        } catch (RuntimeException exc) {
            entity.resetPersistentFlag();
             throw exc;
        }
        return entity;
    }
}

但是直接调用 em.persist(entity) 而没有刷新/刷新会导致同样的问题。

服务调用逻辑:

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public TrustEntity save(TrustEntity dto) {
    TrustEntity  trust = trustDao.store(trust);

    workflowConversation.triggerWorkflow(); // doesn't do anything to any of the entities when they are freshly created

    return trust;
}

任何人都可以帮助我确定这可能有什么问题吗?

4

1 回答 1

0

您不能有一个 OneToMany 既使用 mappedby,使其成为双向,又使用 joincolumn 将其标记为单向。它们发生冲突并导致您出现问题。

当您将关系标记为 mappedby 时,您指定关系的所有信息和控制都在另一端 - 包括 joincolumn 信息。尝试:

TrustEntity {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "trust", cascade = {CascadeType.ALL})
    @PrivateOwned
    private List<TrustIncentiveRateEntity> trustIncentiveRates;
}

TrustIncentiveRateEntity {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TRUST_ID", nullable = false)
    private TrustEntity trust;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "trustIncentiveRate", cascade = {CascadeType.ALL})
    @PrivateOwned
    private List<TrustIncentiveRateValueEntity> trustIncentiveRateValues;
}
于 2013-04-26T14:19:01.600 回答