hibernate 一对多 参照非主键 插入数据库

**

hibernate 单向多对一 参照非主键 插入数据库

当插入数据库记录时,报出外键约束的问题。

表结构如下

其中两张表中id都为业务逻辑无关主键,major表中的 institute_id参照 Institute表中的institute_id, 而Institute表中的institute_id并非主键。

如果你子表参照主表的字段是主键时,就可能不会有一下的错误

-- -----------------------------------------------------
-- Table Institute
-- -----------------------------------------------------
DROP TABLE  Institute ;

CREATE TABLE  Institute(
  id INT NOT NULL IDENTITY,
  institute_id VARCHAR(20) NOT NULL UNIQUE,
  institute_name VARCHAR(45) NOT NULL UNIQUE,
  bean VARCHAR(20) NOT NULL,
  major_amount INT NOT NULL,
  PRIMARY KEY (id))




-- -----------------------------------------------------
-- Table Major
-- -----------------------------------------------------
DROP TABLE Major ;

CREATE TABLE Major (
  id INT NOT NULL IDENTITY,
  major_id VARCHAR(20) NOT NULL UNIQUE,
  major_name VARCHAR(45) NOT NULL,
  institute_id VARCHAR(20),
  PRIMARY KEY (id),
  CONSTRAINT fk_tb_major_tb_institute1
    FOREIGN KEY (institute_id)
    REFERENCES SMS_Institute (institute_id)
	ON DELETE CASCADE
    ON UPDATE  CASCADE)

通过hibernate方向生成的实体类
关联为多对一,major表管理institute表

Institute.class

package com.domain;

import java.util.HashSet;
import java.util.Set;

/**
 * Institute entity. @author MyEclipse Persistence Tools
 */

public class SmsInstitute implements java.io.Serializable {

	// Fields

	private Integer id;
	private String instituteId;
	private String instituteName;
	private String bean;
	private Integer majorAmount;
    //getter和setter方法省略
}

institute.hbm.xml文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.domain.Institute" table="SMS_Institute" >
    
     	<!--业务逻辑无关主键 ,自增-->
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity"></generator>
        </id>
        
        <!--学院ID -->
        <property name="instituteId" type="java.lang.String">
            <column name="institute_id" length="20" not-null="true" unique="true" />
        </property>

		<!--学院名称-->
        <property name="instituteName" type="java.lang.String">
            <column name="institute_name" length="45" not-null="true" unique="true" />
        </property>

		<!--院长-->
        <property name="bean" type="java.lang.String">
            <column name="bean" length="20" not-null="true" />
        </property>

		<!--专业数量-->
        <property name="majorAmount" type="java.lang.Integer">
            <column name="major_amount" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

Major.class

package com.domain;

/**
 * SmsMajor entity. @author MyEclipse Persistence Tools
 */

public class SmsMajor implements java.io.Serializable {

	// Fields

	private Integer id;
	private String majorId;
	private String majorName;
	private SmsInstitute institute;
 	//getter和setter方法省略
}

major.hbm.xml文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Mapping file autogenerated by MyEclipse Persistence Tools -->
<hibernate-mapping>
	<class name="com.domain.SmsMajor" table="Major" >

		<!--业务逻辑无关主键 ,自增-->
		<id name="id" type="java.lang.Integer">
			<column name="id" />
			<generator class="identity"></generator>
		</id>

		<!--专业ID-->
		<property name="majorId" type="java.lang.String">
			<column name="major_id" length="20" not-null="true" unique="true" />
		</property>

		<!--专业姓名-->
		<property name="majorName" type="java.lang.String">
			<column name="major_name" length="45" not-null="true" />
		</property>
		
		<!--单向多对一映射-->
		<many-to-one name="institute" class="com.domain.SmsInstitute" property-ref="instituteId">
			<column name="institute_id" ></column>
		</many-to-one>
	</class>
</hibernate-mapping>

其中many-to-one中的属性property-ref="instituteId"起到重要作用,把外键参考的值指向institute表中的institute_id字段。(ps:可能不设置property-ref属性的话,hibernate会把外键参考的值指向institute表中的主键,也就是我设置的业务逻辑无关主键,从而曝出外键约束错误。可能可能可能,重要的事情说三遍,我也不太确定)

往数据库中插入新纪录

public int insertMajor(String majorId, String majorName, String instituteId) {
		// TODO Auto-generated method stub
		try{
		Session sess=HibernateUtils.getSession();//获取session
		sess.beginTransaction();//开启事务
		InstituteDAOImpl sidi= newInstituteDAOImpl();
		Institute si= sidi.selectByInstituteId(instituteId);//获取所参照学院的对象
		
		//实例化专业对象
		Major major= new Major();
		major.setMajorId(majorId);
		major.setMajorName(majorName);
		major.setInstitute(si);//设置major属性
		sess.save(major);//将专业对象保存到数据库
		sess.getTransaction().commit();
		}catch(Exception e){
			e.printStackTrace();
			return 0;//返回值判断是否插入成功
		}
		
		return 1;

如过many-to-one中没有设置属性property-ref的值,会报外键约束错误,错误提示如下

org.hibernate.util.JDBCExceptionReporter logExceptions
严重: INSERT 语句与 FOREIGN KEY 约束"fk_tb_major_tb_institute1"冲突。该冲突发生于数据库"SMS",表"Institute", column ‘institute_id’。
org.hibernate.exception.ConstraintViolationException: could not insert: [com.domain.Major]

设置好many-to-one中的属性property-ref的值,就不会报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值