【问题标题】:How do I declare a one-to-many Map in Hibernate's XML file?如何在 Hibernate 的 XML 文件中声明一对多映射?
【发布时间】:2017-11-25 23:09:56
【问题描述】:

我正在尝试创建一对多映射关系,但在 Hibernate (4.x) 映射文件中声明它时遇到问题。我只是……想不通。

实体类是这样的,我想使用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。

我不知道该怎么做。所以我知道这是一个基本问题,但是,我应该使用什么映射描述符来完成这项工作?

【问题讨论】:

  • 有人可以拜托赞美我的 ASCII-art 表格,让我今天对自己感觉良好吗?他们花了很长时间!
  • 太棒了!我只想在 SO >.

标签: java hibernate orm hibernate-4.x


【解决方案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

【讨论】:

  • 啊哈!我知道我错过了一些东西 (&lt;one-to-many/&gt;)。太好了,我又可以继续我的统治世界的计划了。
  • 你要快点,我的个人终结者军队的GUI差不多完成了;)
猜你喜欢
  • 2016-07-10
  • 2017-01-09
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-02
  • 1970-01-01
相关资源
最近更新 更多