Hibernate中的unique

本文探讨了Hibernate框架中实现字段唯一性约束的方法及其局限性,通过具体案例分析了如何正确应用这些约束,并强调了数据库层面进行唯一性校验的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表Person
person_id 主键
person_name
passport_id 为外键,关联到表Passport

表Passport
passport_id 主键
country
serial

假设一个Person最多仅有一个Passport,
映射1对1关系
Person.hbm.xml
<many-to-one name="passport" unique="true" class="com.ding.hibernatetest.pojo.Passport" >
<column name="passport_id" length="32" />
</many-to-one>

Passport.hbm.xml
<one-to-one name="person" property-ref="passport" class="com.ding.hibernatetest.pojo.Person" >
</one-to-one>


现在把Passport给某个Person
public void addPassport2Person(String personId, String passportId) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();

Person person = (Person) session.load(Person.class, personId);
Passport passport = (Passport) session.load(Passport.class, passportId);

person.setPassport(passport);

session.getTransaction().commit();
}

我测试了两个数据:

测试1:
String personId = "8ac5061e160f87f001160f87f4740001";
String passportId = "8ac5061e160e694a01160e694dd30001";

test.addPassport2Person(personId, passportId);

测试2:
String personId = "ff8080811610085f0116100862c00001";
String passportId = "8ac5061e160e694a01160e694dd30001";

test.addPassport2Person(personId, passportId);

两个测试都正常完成,都是进行了一个select操作和一个update操作,
但是两个测试的passportId是一样的,这说明两个人共用一个护照,
这和Person.hbm.xml里设置的unique="true"不一致,而Hibernate也没有做检查,想来想去不知什么原因。(注:数据库中没有设置passport_id为unique,我想让Hibernate做检查。)

后来我又做了一个实验,在Person.hbm.xml里,设置person_name为unique
<property name="personName" type="java.lang.String" unique="true" >
<column name="person_name" length="20" unique="true" />
</property>

然后做插入操作,结果相同personName的人也都能插入数据库,Hibernate并没有做检查。
这让我很迷惑,后来查询Hibernate参考文档才明白什么原因。

Hibernate中unique的真正意义是根据hbm生成DDL时,如果设置了unique="true"则生成的表中对应的字段就有unique限制,而我是根据数据库的表生成的hbm,所以hbm中设置的unique="true"是没有任何用处的。

Hibernate不会因为你给这个属性或字段设置了unique为true就给你检查。我们必须让数据库来检查,然后抛出异常。

但是一般的验证流程是表述层-业务逻辑层-数据映射层-数据库,所以最好是提前检查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值