JPA查询误解

时间:2014-09-18 14:23:09

标签: java java-ee jpa eclipselink

我使用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()获得更新的实例。我对此完全感到困惑。

2 个答案:

答案 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 {