2013-05-02 105 views
0

我在项目中使用EclipseLink JPA作为ORM和Web逻辑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> 

SPRING 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" /> 

我的实体CALSS

@Entity 

@Table(name = “PRTY_RQST”) 公共类PrtyRqst实现Serializable {

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它没有工作(DB值是FulorderWSB)。

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

如何得到这个。我已经使用了清晰和关闭的entityManager。谁可以帮我这个事。

谢谢。

维杰。

+0

你是如何从数据库中提取实体的,你可以用相关的代码更新文章。 – 2013-05-02 07:54:29

+0

更新了代码片段。 – user1268890 2013-05-02 08:51:28

回答

1

谢谢,

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

我检查了刷新所有方法的时间都小于500毫秒。当这个线程正在执行并且有一个请求时,我可以预见到唯一的问题。因为它只需要少于500毫秒就可以了。

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

谢谢。

1

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

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

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

+0

谢谢克里斯,我已经添加了这两行this.entityManager.clear(); this.getEntityManager()。refresh(entityManager);到我的API方法,但得到了以下错误“java.lang.IllegalArgumentException:无法刷新没有托管对象:目标工厂的共享EntityManager代理”。你可以帮我吗。 – user1268890 2013-05-02 13:12:44

+0

嗨克里斯,我已经删除刷新和测试清除()。我已将FulfillmentOrderWS的一个值更改为FulfillmentOrderWS123,它对我有效。所以我测试了FulfillmentOrderWS786它为我工作。大。但是当我更换回FulfillmentOrderWS123时,即使对于FulfillmentOrderWS,它仍然可以工作,但值为FulfillmentOrderWS786。我会密切关注并让你知道。 – user1268890 2013-05-02 13:25:31

+0

这意味着它不受管理。你如何得到你的实体?你正在使用Spring,所以我希望你让Spring管理你的EM,所以你应该只需要在新的上下文中再次读入实体 - 尝试调用传入pk的em.find()。这应该返回一个托管实体。如果它仍旧陈旧,请呼叫清除,然后查找或查找,然后在管理实体上刷新。 – Chris 2013-05-02 18:16:26

1

您禁用了缓存,所以您应该看到任何数据库更改。

我的猜测是,你坚持在你的DAO单个EntityManager。这非常糟糕,因为每个事务或每个请求都应创建一个EntityManger,而不是在应用程序的持续时间内进行。它也不是线程安全的,因此保持一个单一的是没有意义的,因为它是一个事务对象。

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

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

+0

谢谢James,我添加了springjpa xml文件。我从你和克里斯的理解是,我需要在执行后关闭事务然后清空它。这样对吗。 – user1268890 2013-05-02 12:58:47

相关问题