我正在使用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的记录。
现在我的问题是为什么没有清除第一级缓存?
答案 0 :(得分:3)
EclipseLink有一个共享对象(第二级)缓存,默认情况下启用,其中包含:
...在持久性单元(EntityManagerFactory, 或服务器)并由所有EntityManagers和用户共享 持久性单位。
如果您根据下面的说明禁用此功能,则应该会看到第二个查询触发。