2014-05-23 23 views
4

我有一個名爲NodeType的類,使用JPA通過SQL Server數據庫支持。JPA比期望更多的實例

沒有什麼特別的,沒有關係,只是一些領域。甚至有更多的人,但爲了簡化我已經忽略它們:

@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,服用性能name爲重點,以發現更容易後來。

在數據庫中,目前有五個項目。

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個實例當前)

示例:在應用程序中,我有一個實例節點類型與值

1 NTYPE_HUP 0   NodeHangup 

Eclipse調試器告訴我說:

  • 在我的地圖,T這裏實際上具有高於
  • map.get回報null如所提到的情況相同的值此實例
  • 15個實例的類NodeType
  • 數據庫中的各行存在一個項目,總是三個實例似乎存在。
  • 比較所有的字段,它們似乎是平等的。即使是字符串id似乎是相同的。不應該getHash()返回相同和equals()應該返回true然後呢?

最後一點讓我震驚,因爲我並沒有在我的應用程序中的任何位置實例化它們!有人知道這是什麼時候發生的嗎?

如果JPA使用緩存(是否?),它應該使用@Id列查看以前創建的項目。即使我做了多個createQuery,他們都應該參考相同的項目。或者我錯了?

這對我來說很奇怪,我不知道如何調試它。

我希望有人能在黑暗中帶來一些光。

編輯:我可以告訴的是,只要我第一次使用相應的JPA請求,就會存在這15個實例。在構造函數中放置一個調試器陷阱,我可以確認所有的實例都是一個接一個地創建的。

EDIT2:的樂趣和測試的緣故,我只是試圖去解決它周圍重新實現hashCode()(簡單return this.id;)和壓倒一切的equals()return this.id == other.id;

的15個實例仍然存在。因爲我只是在閱讀,所以我現在不關心它,因爲我現在可以將所有三個實例視爲一個平等的項目。但這不是解決基本問題的方法。我懷疑這可能發生在其他地方 - 沒有經過測試。

+0

答案可能不是,但只是爲了確保。你在合併實體嗎?合併返回新對象。你JPA的實現是什麼? – skegg99

+0

不,我不知道。正如我所說的:我啓動應用程序,做一些不相關的東西,然後執行某種findAll-query和tadaa,我擁有所有的實例。沒有合併,在這個時候不會調用'persist()'。在代碼中我沒有添加任何東西到這個表中。 – Atmocreations

+0

啊,我的實現是EclipseLink。 – Atmocreations

回答

1

如果我理解的很好,那麼在數據庫中有5個元組,在映射中有5個不同的實例(假設名稱是唯一的?)和JPA加載的15個不同的實例,這些實例與3組相等。

我想這是一個問題Cache Level

如果加載的實例存儲在持久化上下文高速緩存 - 第2級(即EntityManager) - 而不是持久單元高速緩存 - 第1級(即,持續性單元高速緩存)中,EclipseLink可能在讀取同一元組時創建不同的同等實例EntityManagerFactory)。您可能爲每個讀取操作使用不同的EntityManager。在這種情況下,EclipseLink無法找到先前緩存的實體。

這取決於您的應用程序配置。這個問題也可能是由於內存不足和參考緩存較弱造成的。有關詳細說明,請參閱EclipseLink cache documentations頁面。