我在项目中使用EclipseLink JPA作为ORM,使用Web逻辑10.3作为应用程序服务器。一切正常,直到我收到数据刷新的错误。以下是我的实体表行之一更新为新值但我的实体经理或JPA没有选择该值的情况。为此,我们依赖重新启动服务器。然后它拿起了价值。
这是我的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 FILE
<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" />
My Entity 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使用了clear和close。谁可以帮我这个事。
谢谢你。维杰。
答案 0 :(得分:1)
您已关闭EclipseLink共享缓存(AKA二级缓存),因此问题很可能是您持有长期存在的EntityManagers。一旦实体由EM管理,JPA就要求EM从每次查找/查询操作返回该确切实例,就像第一次阅读时以及您的应用可能对其进行的任何更改一样。
有很多选择。最好的方法是查看您的EntityManager生命周期,并在需要时仅获取EntityManager,并在完成后关闭它。或者,只需在点处调用em.clear()以防止它们填满,这将分离与em关联的所有实体。如果您希望在调用clear之前保留更改,请确保刷新更改。
如果您需要刷新特定实体,则em.refresh(实体)将起作用。这将清除应用程序可能已经做出的任何更改,并且与级联刷新设置混合使用延迟访问可能会很危险 - 因此请谨慎使用,否则您可能会在以后无意中消除对整个树的更改。
答案 1 :(得分:1)
您已禁用缓存,因此您应该看到任何数据库更改。
我的猜测是你在DAO中持有一个EntityManager。这非常糟糕,因为每个事务或每个请求都应创建一个EntityManger,而不是在应用程序期间保留。它也不是线程安全的,因此保留一个没有意义,因为它是一个事务对象。
您似乎也在使用Spring,因此它可能代理下面的EntityManager并为每个事务创建一个,但您可能还没有正确配置Spring或您的事务。
包含创建/配置EntityManager的代码。
答案 2 :(得分:1)
谢谢,
获得所有支持。基本上我们没有使用EclipseLink中的Cache。我们有bean作为init方法处理所有元数据初始化。我们所做的是,使用JDK Timer重新加载特定的Bean来刷新数据。它工作正常。
我已经检查了刷新所有方法的时间小于500毫秒。我可以预见只有当这个线程正在执行并且有一个请求时才发出问题。因为它对我们来说不到500毫秒就可以了。
如果有人不使用缓存,我希望这会有所帮助,你可以尝试这种方法。
谢谢。