我正在尝试创建一对多的Map关系,但我在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
支持......不要问):< / p>
<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
用法。
我一直在盯着:
map
,map-key
和element
。String
而不是完整的对象,而且我实际上无法告诉示例代码的用途,因此很难与之相关。 我无法弄清楚该怎么做。所以我知道这是一个基本问题,但是,我应该使用什么映射描述符来使其工作?
答案 0 :(得分: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