1

我在我的项目中使用 EclipseLink JPA 作为 ORM 和 web logic 10.3 作为应用程序服务器。一切正常,直到我遇到数据刷新错误。这是我的实体表行之一更新为新值但我的实体经理或 JPA 没有选择该值的情况。为此,我们有 lite 依赖重新启动了服务器。然后它拿起了价值。

这是我的 persistence.xml 文件,这是我在课堂上使用实体管理器的方式。

<persistence-unit name="BasePersistenceUnit" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/CTH_DS</jta-data-source> 
    <class>org.test.partyrequest.model.dataobject.RqstTrc</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>

    <properties>
        <property name="eclipselink.target-server" value="WebLogic_10" />
        <!-- Logging level is set to INFO, Need to change in Production -->
        <property name="eclipselink.logging.level" value="FINE" />
        <property name="eclipselink.persistence-context.flush-mode" value="COMMIT" />
        <property name="eclipselink.persistence-context.close-on-commit" value="true" />
        <property name="eclipselink.cache.shared.default" value="false" />      
    </properties>
</persistence-unit>

弹簧 JPA XML 文件

<context:load-time-weaver aspectj-weaving="on" />

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="BasePersistenceUnit" />
</bean>

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" />

<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager" /> 

<!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->

<!-- Instruct Spring to perform declarative transaction management automatically on annotated classes. -->
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>

<!-- Post-processor to perform exception translation on @Repository classes
    (from native exceptions such as JPA PersistenceExceptions to Spring's DataAccessException hierarchy).
-->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

我的实体类

@Entity

@Table(name = "PRTY_RQST") 公共类 PrtyRqst 实现可序列化 {

private static final long serialVersionUID = -4679712398918736694L;

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PRTY_RQST_PRTYRQSTID_GENERATOR")
@SequenceGenerator(name = "PRTY_RQST_PRTYRQSTID_GENERATOR", allocationSize = 1, sequenceName = "PRTY_RQST_SEQ")
@Column(name = "PRTY_RQST_ID")
private Long prtyRqstId;

@Column(name = "CHLD_RQST_IND")
private String chldRqstInd;

@Column(name = "PARNT_PRTY_RQST_ID")
private BigDecimal parntPrtyRqstId;

@Column(name = "PROCES_REFR")
private String procesRefr;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "RQST_DT_TM")
private Date rqstDtTm;

@Column(name = "UPDT_BY")
private String updtBy;

// bi-directional many-to-one association to PrtyKey
@OneToMany(mappedBy = "prtyRqst", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<PrtyKey> prtyKeys;

// bi-directional many-to-one association to PrtyRqstHist
@OneToMany(mappedBy = "prtyRqst", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@OrderBy("rqstDtTm DESC")
private List<PrtyRqstHist> prtyRqstHists;

@OneToOne(mappedBy = "prtyRqst", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private RqstPayload rqstPayload;

// bi-directional many-to-one association to RqstTrc
@OneToMany(mappedBy = "prtyRqst", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<RqstTrc> rqstTrcs;

// bi-directional many-to-one association to AddtnRqstInfo
@OneToMany(mappedBy = "prtyRqst", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<AddtnRqstInfo> addtnRqstInfos;

// bi-directional many-to-one association to BusnApplc
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "BUSN_APPLC_ID")
private BusnApplc busnApplc;

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "INTN_PROCES_TYP_ID")
private IntnProcesTyp intnProcesTyp;

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "INTN_STATS_ID")
private IntnStat intnStat;

@Column(name = "ORCHESTRATION_ID")
private String orchestrationId;

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "ALLW_CHNL_ID")
private AllwChnl allwChnl;

// bi-directional many-to-one association to RqstTyp
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "RQST_TYP_ID")
private RqstTyp rqstTyp;

@Column(name = "TRACK_RQST_IND")
private String trackRqstInd;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "SUBMIT_DT_TM")
private Date submitDtTm;

@Temporal(TemporalType.DATE)
@Column(name = "EFFECTIVE_DT")
private Date effectiveDt;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "RQST_CREATE_DT_TM")
private Date rqstCreateDtTm;

在我的 DAO IMPL 类中,我有 this.persist(prtyRqstDO);

@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
    private PartyRequestBO createRequest(PartyRequestBO partyRequestBO, boolean isParent) throws RuntimeException {
        if (log.isDebugEnabled()) {
            log.debug("Enter: PartyRequestsDAOImpl:createRequest()");
        }
        partyRequestBO.setOrchestrationID(generateOrchestrationId());
        PrtyRqst prtyRqstDO = PartyRequestEntityMapper.partyRequestMapper(partyRequestBO, isParent, true);
        try {
            this.persist(prtyRqstDO);
            partyRequestBO.setRequestIdentifier(prtyRqstDO.getPrtyRqstId());
        } catch (Exception e) {
            if(log.isDebugEnabled()) {
                log.debug("PartyRequestsDAOImpl:createRequest : " + PartyRequestConstants.UNABLE_TO_INSERT, e);
            }
            throw new PartyRequestDataException(PartyRequestConstants.UNABLE_TO_INSERT, e);
        }
        if (log.isDebugEnabled()) {
            log.debug("Exit: PartyRequestsDAOImpl:createRequest()");
        }
        return partyRequestBO;
    }


@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
public void persist(T entity) {
    if (log.isDebugEnabled()) {
        log.debug("Enter: BaseDAO:persist() : " + entity);
    }
    this.getEntityManager().persist(entity);
    if (log.isDebugEnabled()) {
        log.debug("Exit: BaseDAO:persist()");
    }
}
public EntityManager getEntityManager() {
    if (log.isDebugEnabled()) {
        log.debug("Enter: BaseDAO:getEntityManager() : " + this.entityManager);
    }
    return this.entityManager;
}

这里的问题是,如果我通过后端更新其中一个表中的行,我的应用程序容器不会选择更改。

有谁能告诉我吗?先感谢您。

编辑:

谢谢你们俩。我已根据您的评论进行了修改,添加了以下代码行。

this.entityManager.clear();
this.entityManager.close();
//this.getEntityManager().refresh(entityManager);

在这里,我可以通过后端获取更新值,而无需重新启动服务器。但问题是它保留了所有更改的值。

例如,我已将值更改为FulOrderWSA它正在工作。更改为FulorderWSB它再次工作。现在我尝试了FulOrderWSZ它没有工作(数据库值是 FulorderWSB )。

最后,我在这里尝试了旧值,即FulorderWSA,根据 DB,它不应该工作,但它对我有用。我注意到它在这里保存了所有数据库更改的值。

如何驾驭这个。我对 entityManager 使用了 clear 和 close。谁可以帮我这个事。

谢谢你。

维杰。

4

3 回答 3

1

您已关闭 EclipseLink 共享缓存(AKA 二级缓存),因此问题很可能是您持有长期存在的 EntityManager。一旦实体由 EM 管理,JPA 要求 EM 从每个查找/查询操作中返回确切的实例,就像第一次读取时一样,以及您的应用程序可能对其进行的任何更改。

有多种选择。最好的办法是查看您的 EntityManager 生命周期,仅在需要时获取 EntityManager,并在完成后关闭它。或者,只需在点处调用 em.clear() 以防止它们被填满,这将分离与 em 关联的所有实体。如果您希望在调用之前保留更改,请确保刷新更改。

如果您需要刷新特定实体,则 em.refresh(entity) 将起作用。这将清除应用程序可能所做的任何更改,并且在级联刷新设置与延迟访问混合时可能会很危险 - 因此请谨慎使用,否则您可能会在以后无意中清除对整个树的更改。

于 2013-05-02T12:33:54.020 回答
1

您已禁用缓存,因此您应该看到任何数据库更改。

我的猜测是你在你的 DAO 中持有一个 EntityManager。这是非常糟糕的,因为应该为每个事务或每个请求创建一个 EntityManger,而不是在应用程序期间保持。它也不是线程安全的,所以保持一个单一的没有意义,因为它是一个事务对象。

您似乎也在使用 Spring,因此它可能正在代理下面的 EntityManager 并为每个事务创建一个,但也许您没有正确配置 Spring 或您的事务。

包括创建/配置 EntityManager 的代码。

于 2013-05-02T12:34:29.273 回答
1

谢谢,

感谢您的支持。基本上我们没有使用来自 EclipseLink 的缓存。我们有 bean 将所有元数据初始化作为 init 方法处理。我们所做的是,使用 JDK Timer 重新加载特定的 Bean 以刷新数据。它工作正常。

我检查了刷新所有方法所花费的时间少于 500 毫秒。我只能预见到这个线程正在执行并且有请求时才会出现问题。因为它花费的时间不到 500 毫秒,这对我们来说没问题。

如果有人不使用缓存,我希望这会有所帮助,您可以尝试这种方法。

谢谢你。

于 2013-05-21T09:41:08.377 回答