2014-05-23 5 views
4

SQL Server 데이터베이스에서 JPA를 사용하여 NodeType이라는 클래스를 지원합니다.JPA 원하는 것보다 더 많은 인스턴스

특별한 것은 없지만 관계가없고 일부 필드 만 있습니다. 이 중 더 있지만, 단순화를 위해 내가 그들을 생략했습니다 : 쉽게 찾을 키로 재산 name을 복용, 내 응용 프로그램을 시작할 때

@Entity 
@Table(name="node_type") 
@NamedQuery(name="NodeType.findAll", query="SELECT n FROM NodeType n") 
public class NodeType implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    private String name; 

    public NodeType() { 
    } 

    public int getId() { 
      return this.id; 
    } 

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

    public String getName() { 
      return this.name; 
    } 

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

} 

, 내가 그들을 읽고 HashMap에 그들 모두를 넣어 후에.

데이터베이스에는 현재 5 개의 항목이 있습니다. 정확히이 각 항목에 대해, 여러 인스턴스를 발생하는 경우

id name  maxNoExits mandatoryExits defaultExits 
== ========= ========== ============== ============ 
1 NTYPE_HUP 0   NodeHangup 
2 NTYPE_ANN 1   NodeAnnounce 
3 NTYPE_SLP 1   NodeWait 
4 NTYPE_XFR 0   NodeTransfer 
5 NTYPE_TBR 32   NodeTimebased 

Somewhen 후, 나는 갑자기

예 (3 개 인스턴스 현재 항목 당) 존재 모르는 : 응용 프로그램에서 내가의 인스턴스가 t, 내지도에서

  • : 값으로 노드 종류는

    1 NTYPE_HUP 0   NodeHangup 
    

    일식 디버거 나에게 그것을 알려줍니다 여기에 실제로

  • 15 인스턴스가 데이터베이스의 각 라인의 클래스 NodeType
  • 존재이 인스턴스에 대한
  • map.get 반환 null 위에 언급 된 인스턴스와 동일한 값을 갖는 항목이며, 항상 세 개의 인스턴스에 보인다 있다.
  • 모든 필드를 비교하면 같을 것입니다. 문자열에 대해서도 id조차도 같은 것으로 보입니다. getHash()과 동일한 것을 반환해야하며 equals()true을 반환해야합니까? 내 응용 프로그램에서 어디서나 instanciating 아니에요으로

마지막 포인트는 나에게 충격! 이 일이 언제 일어나는 지 아십니까?

JPA가 캐시를 사용하면 (?) @Id 열을 사용하여 이전에 생성 된 항목을 찾아야합니다. 비록 내가 하나 이상의 createQuery을하고 있지만, 그들은 모두 같은 항목을 참조해야합니다. 아니면 내가 틀렸어?

나에게있어 모두 이상한 일이며 디버깅 방법을 모르겠습니다.

누군가가 어둠 속에서 빛을 좀 들여 오길 바랍니다.

편집 : 내가 알 수있는 것은 처음으로 해당 JPA 요청을 사용하자마자 15 개의 인스턴스가 존재한다는 것입니다. 생성자에 디버거 트랩을 배치하면 모든 인스턴스가 차례로 생성된다는 것을 확인할 수 있습니다.

Edit2가 : 재미와 테스트를 위해서, 방금

15 개 인스턴스가 여전히 hashCode() (단순히 return this.id;)와 최우선 equals() (return this.id == other.id;를) 다시 구현 주위를 작업했습니다.제가 독서 중일 뿐이므로 현재 세 가지 사례 모두를 동등한 항목으로 간주 할 수 있으므로 현재는 신경 쓰지 않습니다. 그러나 기본 문제에 대한 해결책은 아닙니다. 나는 이것이 다른 곳에서도 일어날 수 있다고 의심한다.

+0

대답은 아마도 아니요. 다만 확인하십시오. 엔티티를 병합 하시겠습니까? 병합은 새 개체를 반환합니다. JPA 구현은 무엇입니까? – skegg99

+0

아니요. 그리고 제가 말했던 것처럼 : 저는 응용 프로그램을 시작하고 무관 한 것들을 수행 한 다음 일종의 findAll-query와 tadaa를 실행합니다. 모든 인스턴스가 있습니다. 이 시점에서'persist()'를 호출하는 것이 아니라 합치는 것이 아닙니다. 어쨌든 코드에서이 테이블에 아무 것도 추가하지 않습니다. – Atmocreations

+0

아, 구현은 EclipseLink입니다. – Atmocreations

답변

1

잘 이해하면 데이터베이스에는 5 개의 튜플이 있고 맵의 고유 인스턴스는 5 개이며 JPA에서로드 한 15 개의 인스턴스는 3 개 그룹으로 동일합니다.

나는 이것이 Cache Level의 문제라고 생각합니다.

로드 된 인스턴스가 Persistence Context Cache - Level 2 (즉, EntityManager)에 저장되어 있고 Persistence Unit Cache - Level 1 (예 : EntityManager)에 저장되어 있지 않은 경우 EclipseLink에서 동일한 튜플에 대해 서로 다른 인스턴스를 만들 수 있습니다. EntityManagerFactory). 각 읽기 작업마다 다른 EntityManager를 사용하는 것이 좋습니다. 이 경우, EclipseLink는 이전에 캐시 된 엔티티를 찾을 수 없습니다.

이것은 응용 프로그램 구성에 따라 다릅니다. 메모리 부족과 약한 참조 캐시로 인해 문제가 발생할 수도 있습니다. 자세한 설명은 EclipseLink cache documentations 페이지에서 확인할 수 있습니다.

관련 문제