事务完成后,JPA第一级缓存未达到

时间:2015-04-24 12:51:38

标签: jpa jpa-2.0 jpa-2.1

我正在使用JPA 2.1(带有EclipseLink实现),从数据库中获取记录。 默认情况下,启用第一级缓存,它将记录缓存在PersistenceContext中。如果我尝试获得相同的记录,我将从第一级缓存中获取它,因此第二次不会在数据库上触发查询。

一旦事务结束,第一级缓存将被清除,如果我再次尝试获取相同的条目,则必须在清除缓存时触发查询,并且它应该来自数据库但不是。

如果我关闭当前的实体管理器,重新打开它并尝试获取记录,至少应该对数据库触发查询。

即使现在第二个查询也不会进入数据库。一旦我第一次从数据库中获取记录(此时我可以在控制台日志中看到选择查询),在病房之后如果我再试一次,它来自缓存(因为我看不到查询)更多时间在控制台日志中,我假装它来自缓存),无论我做什么(使用新事务或关闭并重新打开实体管理器),都不会清除第一级缓存。

我正在使用的代码如下:

EntityManagerFactory entityManagerFactory=
            Persistence.createEntityManagerFactory("01EmployeeBasics");

    EntityManager entityManager=entityManagerFactory.createEntityManager();
    System.out.println("EM1 : "+entityManager);
    entityManager.getTransaction().begin();
    System.out.println("Tx1 : "+entityManager.getTransaction());
    Employee employee=entityManager.find(Employee.class, 123);
    entityManager.getTransaction().commit();
    entityManager.close();

    entityManager=entityManagerFactory.createEntityManager();
    System.out.println("EM2 : "+entityManager);
    entityManager.getTransaction().begin();
    System.out.println("Tx2 : "+entityManager.getTransaction());
    Employee employee2=entityManager.find(Employee.class, 123);
    entityManager.getTransaction().commit();
    entityManager.close();

    entityManagerFactory.close();

员工类如下:

package in.co.way2learn;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Employee {

@Id
private int id;

private String name;
private int salary;

public Employee() {
    // TODO Auto-generated constructor stub
}

public Employee(int id, String name, int salary) {
    super();
    this.id = id;
    this.name = name;
    this.salary = salary;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    System.out.println("Employee.getName()");
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getSalary() {
    return salary;
}

public void setSalary(int salary) {
    this.salary = salary;
}

}

在数据库中有一条id为123的记录。

现在我的问题是为什么没有清除第一级缓存?

1 个答案:

答案 0 :(得分:3)

EclipseLink有一个共享对象(第二级)缓存,默认情况下启用,其中包含:

  

...在持久性单元(EntityManagerFactory,   或服务器)并由所有EntityManagers和用户共享   持久性单位。

如果您根据下面的说明禁用此功能,则应该会看到第二个查询触发。

https://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching