2009-12-04 2 views
2

최신 상태가 아닌 데이터를 반환하는 Hibernate 백업 Jpa 쿼리에 문제가 발생했습니다. 데이터베이스 자체 대신 캐시에서 데이터를 가져 오는 것이 문제라고 가정합니다.데이터베이스 대신 캐시에서 가져 오는 Jpa 쿼리?

예를 들어 한 페이지에서 개체를 변경하고 유지 한 다음 데이터베이스의 행을 나열하는 이전 페이지로 돌아가서 변경하기 전에 존재했던 개체를 표시합니다. 내 DAO의 쿼리 기록이 내 로그에 표시 될 수 있으며 데이터베이스에 들어가서 변경 사항이 지속되었음을 확인할 수 있지만 JPA는 다음 페이지로 이동할 때 데이터베이스에서 데이터를 가져 오지 않습니다.

다른 웹 브라우저에서 페이지를로드 할 때 업데이트 된 데이터베이스보기가 표시되지 않기 때문에 일종의 세션 캐싱이있을 수 있습니다.

이 문제를 어떻게 해결합니까?

편집 : 내 MVC 프레임 워크 (스프링 MVC)가 아무 것도 캐시하고 있지 않은지 확인하기 위해 컨트롤러를 로깅하는 것을 포함하여 몇 가지 후속 테스트를 수행했습니다. 컨트롤러 수준에서도 오래된 데이터베이스 정보를 볼 수 없습니다.


다음은 ORM 항목 파일의 매핑 스 니펫입니다.

private static final long serialVersionUID = 1L; 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Basic(optional = true) 
@Column(name = "ID", nullable = false) 
private Integer id; 
@Basic(optional = false) 
@Column(name = "Name", nullable = false, length = 100) 
private String name; 
@Basic(optional = false) 
@Column(name = "DayOffset", nullable = false) 
private int dayOffset; 
@Basic(optional = false) 
@Column(name = "StartTime", nullable = false, length = 5) 
private String startTime; 
@Basic(optional = false) 
@Column(name = "Enabled", nullable = false) 
private boolean enabled; 
@Basic(optional = false) 
@Column(name = "LastTouched", insertable = false, updatable = false, nullable = 
false) 
@Temporal(TemporalType.TIMESTAMP) 
private Date lastTouched; 
@Column(name = "TouchedBy", length = 50) 
private String touchedBy; 
@JoinTable(name = "ReconciliationSearchRule", 
joinColumns = {@JoinColumn(name = "ReconciliationId", 
    referencedColumnName = "ID", nullable = false)}, 
inverseJoinColumns = {@JoinColumn(name = "SearchRuleId", 
    referencedColumnName = "ID", nullable = false)}) 
@ManyToMany(fetch = FetchType.LAZY) 
private Collection<SearchRule> searchRuleCollection; 
@JoinColumn(name = "ServerId", referencedColumnName = "ID", nullable = false) 
@ManyToOne(optional = false, fetch = FetchType.LAZY) 
private Server server; 
@OneToMany(mappedBy = "reconciliation") 
private Collection<Report> reportCollection; 
+0

"DAO에서 내 쿼리가 불 수 있습니다"라는 의미는 무엇입니까?SQL이 데이터베이스로 전송되는 것을 보시겠습니까? 처음부터 변화를 올바르게 지속하고 있음을 어떻게 알 수 있습니까? JPA 제공 업체 인 –

+0

은 무엇입니까? – Bozho

+0

엔티티는 어떻게 저장합니까? EntityManager.persist() 또는 .merge()? – Bozho

답변

3

무슨 일인지 알아 냈습니다. DAO를 사용할 때마다 Backing EntityManager가 만들어 지도록 내 DAO를 프로토 타입 (일명 non-singleton)으로 주입하고 있습니다. EntityManager 외부의 데이터베이스 변경 사항은 특정 EntityManager에 대한 쿼리에 의해 등록되지 않습니다.

물론 DAO를 싱글 톤으로 설정하면 내 응용 프로그램의 멀티 스레드 부분에서 다른 문제가 발생하지만 이는 다른 문제입니다.

0

이것에 대해가는 몇 가지 방법이 있습니다 :

  1. 문제의 실체에 @DataCache(timeout = 1000)를 사용하여 사용중인 객체 유형에 대한 합리적인 뭔가로 설정 퇴거 전략을 설정합니다.
  2. 엔티티 또는 클래스의 evict(...)으로 전화하십시오. 구현 세부 사항은 사용중인 공급자 (예 : 최대 절전 모드)에 따라 다릅니다.
+0

1에 대해 @DataCache가 더 자세히 설명 할 수 있습니까? 2의 경우, 어떤 클래스에 축출 메소드가 있습니까? 고맙습니다. –

+0

Hibernate Session에 evict()가 적합하지 않습니다.) – Bozho

+0

@DataCache는 캐쉬되기 때문에 새로 고치지 않은 클래스에 넣는 주석입니다. 이 주석은 JPA에게 timeout 매개 변수를 통해 지정된 빈도로이 유형의 객체에 대한 캐시를 제거 (또는 제거)하도록 지시합니다. – rynmrtn

0

예를 들어, 나는 변경하고 한 페이지에 객체를 유지 한 후 데이터베이스의 행을 나열 이전 페이지로 돌아가서, 그들이 변경 이전에 존재했던이 개체를 표시합니다 .

2 수준 캐시 관리는 투명해야한다, 당신은 evict()에 수동으로 업데이트 후, 2 레벨 캐시는 "자동으로"최대 절전 모드로 목표 테이블에 대해 무효가됩니다 엔티티가 없습니다.

제 질문은 다음과 같습니다. 의 의미는 "이전 페이지로 돌아 가기"? 네비게이터 "뒤로"버튼 사용을 의미합니까? 페이지를 새로 고쳤습니까? 이 점을 분명히 할 수 있습니까?

또한 매핑 파일이나 주석 처리 된 엔터티를 게시 할 수 있습니까?

+0

파스칼, 돌아가서 다른 페이지로 연결되는 하이퍼 링크를 클릭하십시오. 나는 월요일에 일할 때 좀 더 많은 정보를 올릴 것입니다. –

관련 문제