2013-05-02 183 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

相關問題