Hibernate中的"Repeated column in mapping for entity"异常

[url]http://www.muxuanli.com/lmx/[/url]

一对多双向关联(类Item与类Bid):

Item类:

public class Item {
private int id;
private String name;
private Set bids = new HashSet();
•••
}

Bid类:

public class Bid {
private int id;
private double amount;
private Item item;
•••
}

Item.hbm.xml:(t_item表)

<hibernate-mapping>
•••
<set name="bids" table="t_bid" cascade="save-update">
<key column="item_id" not-null="true"/>
<one-to-many class="value.Bid"/>
</set>
•••
</hibernate-mapping>

Bid.hbm.xml: (t_bid表)

<hibernate-mapping>
•••
<many-to-one name="item" class="value.Item" column="item_id" not-null="true" />
•••
</hibernate-mapping>

测试代码:

•••
Item item = new Item();
item.setName("item");

Bid b1 = new Bid();
b1.setAmount(12.09);
b1.setItem(item);

Bid b2 = new Bid();
b2.setAmount(11.98);
b2.setItem(item);

Set bids = new HashSet();
bids.add(b1);
bids.add(b2);

item.setBids(bids);

session.beginTransaction();
session.save(item);
session.getTransaction().commit();

这是以前的一个"一对多双向关联",今天运行时抛出了如下异常:

Exception in thread "main" java.lang.ExceptionInInitializerError
•••
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: value.Bid column: item_id (should be mapped with insert="false" update="false")


仔细检查了映射文件,发现在Item.hbm.xml配置文件的<key>元素中多了一个not-null="true"限制,将其去掉后就可以正常运行。

[b](1)[/b] 加入not-null="true"意味着什么?

由<key>元素定义的列映射item_id是t_bid表的外键列。加入not-null="true"之后,意味着如果要增加t_bid表中的记录,那么外键列item_id一定不能为null,Item端为了确保item_id字段不为null(Item端不知道Bid端的情况,所以它不可能依赖Bid端来确保item_id不为空),会在t_bid的插入语句中为该字段赋值。
[b]事实上,不论是单向一对多还是双向一对多,只要在<key>元素中设置了not-null="true",那么在t_bid表的insert语句中都会增加column属性所指定的列(此处即item_id),以此确保item_id列不为空。[/b]以单向一对多关联为例:如果未设定not-null="true",那么输出的语句为:Hibernate: insert into t_bid (amount) values (?);而如果设定了not-null="true",那么输出的语句就是:Hibernate: insert into t_bid (amount, item_id) values (?, ?) 。

[b](2) [/b]抛出异常的原因?

异常的原因可以从异常信息中看出,即字段重复。通过(1)中的分析,可以很清楚地明白其中的原因。查看Bid.hbm.xml映射文件:
<many-to-one name="item" class="value.Item" column="item_id" not-null="true" />
可以看出,这是一个多对一关联,not-null="true"表明一个Bid肯定有其对应的Item实体。column属性指定t_bid表中item_id列是t_item表主键的一个外键。[b]对于Bid而言,不论是否指定了not-null="true",它的insert语句都会为item_id字段赋值,即使为null。[/b]这就是异常产生的原因,这样的设置会使Hibernate发出类似 insert into t_bid (item_id,item_id) values (•••)的语句,所以会提示重复字段异常。

[b](3)[/b] 解决:
1. 把<key>元素中的not-null="true"去掉,事实上在双向关联中根本不需要由Item端来确保外键列item_id不为null。
2. 可以按照提示,在Bid.hbm.xml映射文件中加入insert="false" update="false"。
[b]加入这两个限制,意味着对t_bid表的insert与update操作中不包含这个字段[/b],这样可避免重复。
3. 在Item.hbm.xml中的<set>元素内加入inverse="true",将关联关系全部交给Bid端。[url]http://lijiejava.iteye.com/blog/776587[/url]
4. 最无聊的方法:将<key>元素中的column值改成item_id_1等,不与item_id重复,这样会导致数据表字段的冗余,不应该使用。

在实际应用中,不应该在<key>中加入not-null="true"限制。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值