2017-06-22 47 views
1

我正試圖創建一個一對多的Map關係,並且在Hibernate(4.x)映射文件中聲明它時遇到了麻煩。我只是......無法弄清楚。如何在Hibernate的XML文件中聲明一對多的Map?

的實體類是這樣的,在這裏我想用IPLogEntry#ip爲地圖鍵(這是不可改變的)

class User { 

    private long id; 
    private Map<String,IPLogEntry> ipHistory = new HashMap<String,IPLogEntry>(); 
    ... other fields; 

    public void addIPEntry (String ip) { 
     IPLogEntry e = ipHistory.get(ip); 
     if (e == null) { 
      e = new IPLogEntry(this, ip); 
      ipHistory.put(ip, e); 
     } 
     e.doOtherStuff(...); 
    } 

} 

class IPLogEntry { 

    private long id; 
    private User user; 
    private String ip; 
    ... other fields; 

    IPLogEntry (User user, String ip) { 
     this.user = user; 
     this.ip = ip; 
     ... init other fields; 
    } 

} 

和表所示:

╔═══════════════════╗ ╔══════════════════════════════════════════════════╗ 
║ users    ║ ║ ip_log           ║ 
╟─────────────┬─────╢ ╟─────────────┬───────────────┬──────────────┬─────╢ 
║ id (bigint) │ ... ║ ║ id (bigint) │ user (bigint) │ ip (varchar) │ ... ║ 
╚═════════════╧═════╝ ╚═════════════╧═══════════════╧══════════════╧═════╝ 

注意ip_log.ip是地圖鍵IPLogEntry#ip字段值。

和一堆揮手我有這個在映射失敗的嘗試後(順便說一句,我不需要級聯delete支持現在...不要問):

<class name="d13.dao.User" table="users"> 
    <id name="id"><generator class="native"/></id> 
    <map name="ipHistory" cascade="save-update,merge"> 
     <key column="user"/> 
     <map-key column="ip" type="string"/> 
     <element type="d13.dao.IPLogEntry"/> 
    </map> 
    ... 
</class> 

<class name="d13.dao.IPLogEntry" table="ip_log"> 
    <id name="id"><generator class="native"/></id> 
    <many-to-one name="user" class="d13.dao.User" not-null="true"/> 
    <property name="ip" not-null="true"/> 
    ... 
</class> 

這讓我這個在初始化:

Error: creating static hibernate session factoryCould not determine type for: 
    d13.dao.IPLogEntry, 
    at table: users_ipHistory, 
    for columns: [org.hibernate.mapping.Column(elt)] 

我覺得IPLogEntry側是正確的,它的User側和我遇到麻煩的map使用。

我一直盯着:

  • The Hibernate Manual,但我不能換我的頭周圍mapmap-keyelement
  • This "tutorial",但它使用基本的String而不是一個完整的對象作爲元素類型,而且我也不能真正知道該示例代碼服務的目的是什麼,因此很難與之相關聯。
  • This wikibooks page,但它是JPA映射而不是Hibernate。

我不知道該怎麼做。所以我知道這是一個基本問題,但是,我應該使用什麼映射描述符來實現這個工作?

+0

有人可以*請*讚美我的ASCII藝術表,以便我今天能對自己感覺良好?他們花了很長時間! –

+1

太棒了!我只是想在這裏的表格上使用''''''''格式的工具。< –

回答

1

嗯,這是非常簡單,標註爲基礎的繪圖

@OneToMany(mappedBy = "user", cascade = { PERSIST, MERGE }) 
@MapKey(name = "ip") 
private Map<String, IPLogEntry> ipHistory = new HashMap<>(); 

我不是在XML映射經歷,但它應該是:

<class name="d13.dao.User" table="users"> 
    <id name="id"> 
     <generator class="native"/> 
    </id> 
    <map name="ipHistory" cascade="save-update,merge" inverse="true"> 
     <key column="user_id"/> 
     <map-key column="ip" type="string"/> 
     <one-to-many class="d13.dao.IPLogEntry"/> 
    </map> 
    ... 
</class> 

<class name="d13.dao.IPLogEntry" table="ip_log"> 
    <id name="id"> 
     <generator class="native"/> 
    </id> 
    <many-to-one name="user" class="d13.dao.User" column="user_id" not-null="true"/> 
    <property name="ip" not-null="true"/> 
    ... 
</class> 

Example 7.29. Bidirectional association with indexed collection

+0

啊哈!我知道我錯過了一些東西('<一對多/>')。優秀的,我可以再次繼續我的統治世界的計劃。 –

+1

你必須快點,我幾乎完成了我的個人終結者軍隊的GUI;) –