我使用JPA(EclipseLink)。我有实体类
@Entity
@Table(name = "my_table")
public class MyEntity implements java.io.Serializable {
@Id
@Column(name = "id")
int id;
@Column(name = "name")
String name;
@Lob
@Column(name = "data")
byte[] bytes;
//getters und setters are ommited
}
我有这样的查询
Query query = entityManager.createQuery("SELECT m FROM MyEntity m WHERE m.name = :name");
第一次获得结果后,数据库中的data
字段发生了变化。但是当我下次运行这个查询时,我仍然会得到旧的价值。任何人都可以向我解释这种行为并向我展示如何获得更新值
UPD:我致电query.getResultList()
并获取MyEntity的实例。然后其他应用程序更改数据库中的数据并提交它(我可以运行sql语句,我看到它真的提交)。然后我再次调用query.getResultList()
并获取包含旧数据的MyEntity实例。我的应用程序使用事务隔离级别TRANSACTION_READ_COMMITTED。我已经通过
Connection c = entityManager.unwrap(Connection.class);
c.getTransactionIsolation();
UPD2:我注意到当我调用上面的语句entityManager.unwrap(Connection.class)
时,行为就像在此调用后清除缓存一样。在此调用之后,我通过调用query.getResultList()
获得更新的实例。我对此完全感到困惑。
答案 0 :(得分:0)
由于另一个应用程序正在更改数据,因此您的缓存已过时。因此,您的问题基本上与以下内容重复:EntityManager doesn't see changes made in other transactions
请尝试在那里接受的答案中提出的建议,看看它对您的问题有何作用。
编辑:清除缓存通常依赖于供应商,因此您必须为您的提供商搜索文档。对于EclipseLink,这看起来很有希望:http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching#How_to_refresh_the_cache
EDIT2:由于您使用EntityManager,您可以直接尝试:
em.getEntityManagerFactory().getCache().evictAll();
答案 1 :(得分:0)
如果您不希望缓存实体,可以尝试将其标记为不可缓存:@Cacheable(false)
@Entity
@Table(name = "my_table")
@Cacheable(false)
public class MyEntity implements java.io.Serializable {