我遇到一个在tomcat中运行的webapp的问题,我有一个抽象的DAO类,其中有一个名为all()的方法,它返回数据库或JPA缓存中的所有实体。它似乎在初始调用时正确返回实体,但后续调用不反映从单独的UI调用发生的更新,这些调用将使用实体管理器find方法从列表中查找特定实体,更新相关字段并提交。当我通过相同的all()方法查看该列表后,我仍然看到原始值。如果我在日志中进行另一次更新,我可以看到值从正确的值(不是原始值)更改为更新的值,并且日志显示每次都正确发生的更新。
我正在使用guice进行注射。我已经玩过日志记录,并且可以在整个请求中使用的实体管理器上看到相同的哈希码,但每个请求都有不同的哈希码。我玩过以下persistance.xml文件,它似乎没有任何帮助...
<property name="eclipselink.cache.shared.default" value="false" />
<shared-cache-mode>NONE</shared-cache-mode>
我不明白为什么我的all()不会返回更新的结果,我也尝试添加代码来查找我在列表中更新的特定实体,然后通过调用以下内容替换它... < / p>
entity = em.find(Class.class, id)
这似乎解决了该特定实体的问题,因此看起来我的查询重用旧版本。
这是我的DAO课程的片段
private final Provider<EntityManager> emP;
protected EntityManager em(boolean useTransaction) throws DaoException {
return useTransaction ? begin() : emP.get();
}
public List<T> all() throws DaoException {
EntityManager em = em(false);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(eClass);
Root<T> from = cq.from(eClass);
return em.createQuery(cq.select(from)).getResultList();
}
public T save(T t) throws DaoException {
return save(t, em(true));
}
protected T save(T t, EntityManager em) throws DaoException {
if (Objects.isNull(t)) {
throw new DaoException("can't save null object: " + getDaoClass(), new NullPointerException());
}
T saved;
if (t.getId() > 0) {
saved = em.merge(t);
} else {
em.persist(t);
saved = t;
}
autoCommit();
return saved;
}
protected void autoCommit() throws DaoException {
if (autoCommit) {
commit();
}
}
public void commit() throws DaoException {
EntityManager em = emP.get();
if (!em.getTransaction().isActive()) {
throw new DaoException("transaction isn't active, unable to commit");
}
try {
em.getTransaction().commit();
} catch (IllegalStateException e) {
throw new DaoException("transaction not active", e);
} catch (RollbackException e) {
throw new DaoException("commit rolled back", e);
}
}
所以我想知道是否有人对此可能发生的原因有任何见解,或者对我还能尝试检查的其他方面有任何建议?
答案 0 :(得分:0)
所以我找到了我遇到的问题的原因。我在引用列表时在我的实体中使用ElementCollection注释。我删除了注释并将其替换为JoinTable和OneToMany注释,并且工作正常。
我遇到的问题是该实体将存储在数据库中,我按预期更新了该实体,但JPA已嵌入了引用它的实体列表。
所以我看到每次返回的嵌入列表都不是我更新的实际实体。我的实体现在使用正确的连接表而不是嵌入的对象,一切都按预期运行。