2017-06-22 46 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;) –