对《深入浅出hibernate》一书中one-to-one主键关联映射疑惑

本文探讨了在使用Hibernate框架实现一对一关联映射时遇到的问题,通过对比书中示例与实际代码,分析了异常原因,并给出了修改建议。

这两天在研究hibernate,发现<<深入浅出hibernate>>一书挺好,清晰易懂,只是在看到one to one 主键关联映射的地方,有些疑惑。

 

关系模型是这样的,很简单,如下:

 

T_Person

id  number(11) <pk,fk>

name varchar2(50)

age number(3)

.....

 

 

T_PASSPORT

id number(11) <pk>,

serial varchar2(20),

expiry number(11)

 

如上,T_Person的id即是主键又是外键,引用T_PASSPORT的主键字段id.并且它们是一对一的关系。

 

对应的实体类如下:

 

 

TPerson implents Serializable
+TPerson

id:Integer

age:Integer

name:String

passport:TPassport

 

 

 

TPassport implents Serializable
+Tpassport

id:Integer

serial:String

expiry:Integer

person:Tperson

 

实体关系如上,它们建立了双向一对一关系,具体映射文件如下:

 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping
     PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping>
	<class name="com.alcatel.cn.hibernate.ORMapping.onetoone.pojo.TPerson" table="T_PERSON">
		<id name="id" column="id" type="java.lang.Integer">
		<generator class="sequence">
				<param name="sequence">person_seq</param>
			</generator>
		</id>
		<property name="name" type="string" column="name"></property>
		<property name="age" type="java.lang.Integer" column="age"></property>
		<one-to-one name="passport"  class="com.alcatel.cn.hibernate.ORMapping.onetoone.pojo.TPassport"
					cascade="all"
					outer-join="true"/>
	</class>
</hibernate-mapping>     

 

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping
     PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping>
	<class name="com.alcatel.cn.hibernate.ORMapping.onetoone.pojo.TPassport" table="T_PASSPORT">
		<id name="id" column="id" type="java.lang.Integer">
			
			<generator class="foreign">
				<param name="property">person</param>
			</generator>
			
		</id>
		<one-to-one name="person"
					class="com.alcatel.cn.hibernate.ORMapping.onetoone.pojo.TPerson"
					constrained="true"
					></one-to-one>
		<property name="serial" type="string" column="SERIAL"></property>
		<property name="expiry" type="java.lang.Integer" column="EXPIRY"></property>
	</class>
</hibernate-mapping>

 

 

    测试代码如下:

 

 

package com.alcatel.cn.hibernate.ORMapping.onetoone.test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.alcatel.cn.hibernate.ORMapping.onetoone.pojo.TPassport;
import com.alcatel.cn.hibernate.ORMapping.onetoone.pojo.TPerson;
import com.alcatel.cn.hibernate.common.HibernateUtil;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Session s=HibernateUtil.currentSession();
		
		TPerson p=new TPerson();
		p.setAge(20);
		p.setName("Sunrui");
		
		TPassport passport=new TPassport();
		passport.setSerial("PCN759386");
		passport.setExpiry(new Integer(2));
		
		//相互设置关联
		passport.setPerson(p);
		p.setPassport(passport);
		
		
		try{
			Transaction tx=s.beginTransaction();
			
			s.save(p);//注意:这里只对Person进行保存
			tx.commit();
			
			TPassport pp=(TPassport)s.load(TPassport.class, new Integer(5));
			System.out.println("Passport Serial ==>"+pp.getSerial());
			System.out.println("Person name==>"+pp.getPerson().getName());
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}

 

运行,出现如下异常:

 

Hibernate: select person_seq.nextval from dual
Hibernate: insert into T_PERSON (name, age, id) values (?, ?, ?)
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
	at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:92)
	at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
	at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:218)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2159)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2595)
	at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:51)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
	at com.alcatel.cn.hibernate.ORMapping.onetoone.test.Test.main(Test.java:36)
Caused by: java.sql.BatchUpdateException: ORA-02291: integrity constraint (HIBERNATE.FK_PASSPORT) violated - parent key not found

 

 

 

仔细把自己的代码与书中的实例对照了下,发现没有任何差错,但确确实实发生异常了。仔细分析了下,这个异常是违反了约束性,第一想到的是违反了外键约束,看看日志(阴影部分),它确实是先往T_Person表里插入记录,当然找不到对应的T_Passport的id,违反了外键约束。

 

我尝试了把Person.hbm.xml与Passport.hbm.xml中配置方式互换,即让Passport.hbm.xml维护主键生成,然后Person.hbm.xml配置外键生成方式。运行完好。

 

这里,我从不怀疑<<深入浅出Hibernate>>作者的水平,他们确实都是比较牛的人物,也是我的偶像,像夏昕写的spring,hibernate等都是非常难得的好书。

 

所以,是不是我用的是hibernate3.0,而书本中用的是hibernate2.0等原因造成的?很迷茫。

 

 

 

【无线传感器】使用 MATLAB和 XBee连续监控温度传感器无线网络研究(Matlab代码实现)内容概要:本文围绕使用MATLAB和XBee技术实现温度传感器无线网络的连续监控展开研究,介绍了如何构建无线传感网络系统,并利用MATLAB进行数据采集、处理与可视化分析。系统通过XBee模块实现传感器节点间的无线通信,实时传输温度数据至主机,MATLAB负责接收并处理数据,实现对环境温度的动态监测。文中详细阐述了硬件连接、通信协议配置、数据解析及软件编程实现过程,并提供了完整的MATLAB代码示例,便于读者复现和应用。该方案具有良好的扩展性和实用性,适用于远程环境监测场景。; 适合人群:具备定MATLAB编程基础和无线通信基础知识的高校学生、科研人员及工程技术人员,尤其适合从事物联网、传感器网络相关项目开发的初学者与中级开发者。; 使用场景及目标:①实现基于XBee的无线温度传感网络搭建;②掌握MATLAB与无线模块的数据通信方法;③完成实时数据采集、处理与可视化;④为环境监测、工业测控等实际应用场景提供技术参考。; 阅读建议:建议读者结合文中提供的MATLAB代码与硬件连接图进行实践操作,先从简单的点对点通信入手,逐步扩展到多节点网络,同时可进步探索数据滤波、异常检测、远程报警等功能的集成。
内容概要:本文系统讲解了边缘AI模型部署与优化的完整流程,涵盖核心挑战(算力、功耗、实时性、资源限制)与设计原则,详细对比主流边缘AI芯片平台(如ESP32-S3、RK3588、Jetson系列、Coral等)的性能参数与适用场景,并以RK3588部署YOLOv8为例,演示从PyTorch模型导出、ONNX转换、RKNN量化到Tengine推理的全流程。文章重点介绍多维度优化策略,包括模型轻量化(结构选择、输入尺寸调整)、量化(INT8/FP16)、剪枝与蒸馏、算子融合、批处理、硬件加速预处理及DVFS动态调频等,显著提升帧率并降低功耗。通过三个实战案例验证优化效果,最后提供常见问题解决方案与未来技术趋势。; 适合人群:具备定AI模型开发经验的工程师,尤其是从事边缘计算、嵌入式AI、计算机视觉应用研发的技术人员,工作年限建议1-5年;熟悉Python、C++及深度学习框架(如PyTorch、TensorFlow)者更佳。; 使用场景及目标:①在资源受限的边缘设备上高效部署AI模型;②实现高帧率与低功耗的双重优化目标;③掌握从芯片选型、模型转换到系统级调优的全链路能力;④解决实际部署中的精度损失、内存溢出、NPU利用率低等问题。; 阅读建议:建议结合文中提供的代码实例与工具链(如RKNN Toolkit、Tengine、TensorRT)动手实践,重点关注量化校准、模型压缩与硬件协同优化环节,同时参考选型表格匹配具体应用场景,并利用功耗监测工具进行闭环调优。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值