2015-04-24 3 views
0

Я использую JPA 2.1 (с реализацией EclipseLink), чтобы получить запись из базы данных. По умолчанию этот кеш первого уровня включен, он кэширует запись в PersistenceContext. Если я попытаюсь получить такую ​​же запись, я получу ее из кеша первого уровня, поэтому второй запрос не будет запущен во второй раз.Кэш первого уровня JPA не был обнаружен после завершения транзакции

Как только транзакция закончится, кеш первого уровня будет очищен, и если я попытаюсь получить такую ​​же запись еще раз, запрос должен быть запущен, так как кеш очищается, и он должен поступать из базы данных, но это не так.

По крайней мере, запрос должен быть запущен в базе данных, если я закрываю текущий диспетчер объектов, повторно его открываю и пытаюсь получить запись.

Даже сейчас второй запрос не поступает в базу данных. Как только я получаю запись из базы данных в первый раз (в это время я вижу запрос выбора в журналах консоли), после того, как подопечные, если я попытаюсь получить еще один раз, его выход из кеш-памяти (поскольку я не вижу запрос один больше времени в консольных журналах, я притворяюсь, что он исходит из кеша), независимо от того, что я делаю (использовать новую транзакцию или закрыть и повторно открыть диспетчер сущностей), кеш первого уровня не очищается.

код, который я использую ниже:

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(); 

класс Employee, как показано ниже:

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; 
} 

} 

В базе данных имеется запись с идентификатором 123.

Теперь мой вопрос почему кеш первого уровня не очищается ???

+0

и если кэш l1 не очищается, то вы можете убедиться, что, проверяя, если объект еще управляет EntityManager, вы сделали это? или вы просто предполагаете, что кеш l1 не очищается? Очевидно, что кеш l1 будет ТОЛЬКО очищаться, когда EM закрыт, а не tx (в зависимости от типа PersistenceContext - какой тип вы используете?) –

ответ

3

EclipseLink имеет общий объект (второй уровень) кэша, который включен по умолчанию, и который:

... существует для длительности персистенции блока (EntityManagerFactory, или сервер) и является общим всех EntityManager и пользователей модуля останова .

Если вы отключите его в соответствии с инструкциями ниже, вы должны увидеть 2-й запрос.

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