`

Hibernate级联cascade 完整实例 及 错误解决(mysql)

阅读更多

最近在学习Hibernate(基于《深入浅出Hibernate》一书),在动手练习的时候,出现了一些问题,并加以解决,现将其罗列如下:

 

数据库表创建:

 

CREATE TABLE `t_user` (    
  `id` int(11) NOT NULL AUTO_INCREMENT,    
  `name` varchar(45) default NULL,    
  `age` int(3) default NULL,    
  `group_id` int(11) default NULL,    
  PRIMARY KEY  (`id`)    
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 

 

CREATE TABLE `t_passport` (      
  `id` int(11) NOT NULL ,      
  `serial` varchar(30) default NULL,      
  `expiry` int(11) default NULL,         
  PRIMARY KEY  (`id`)      
) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
 

 

 

配置文件:

 

<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
			    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>	

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
	  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
	  <property name="url" value="jdbc:mysql://localhost:3306/test" />
	  <property name="username" value="root" />
	  <property name="password" value="123" />
	  <property name="maxActive" value="64"/>
	  <property name="maxIdle" value="2" />
	  <property name="maxWait" value="10" />
	 <!--  <property name="validationQuery" value="select sysdate from dual" /> -->
	  <property name="testWhileIdle" value="true" />
	  <property name="timeBetweenEvictionRunsMillis" value="60000" />
	  <property name="minEvictableIdleTimeMillis" value="60000" />
	  <property name="removeAbandoned" value="true" />
</bean>

	<bean id="mySessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
        <property name="dataSource"><ref local="myDataSource"/></property>
		<property name="mappingResources">
			<list>
			<!-- 	<value>com/chinabank/b2c/hbm/Person.hbm.xml</value>
				<value>com/chinabank/b2c/hbm/Address.hbm.xml</value> -->
				<value>com/chinabank/b2c/hbm/TUser.hbm.xml</value>
				<value>com/chinabank/b2c/hbm/TPassport.hbm.xml</value>
			</list>
		</property>
		
		<property name="hibernateProperties">
			<props>
				<!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>-->
				<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
				<prop key="hibernate.proxool.existing_pool">true</prop>
				<prop key="hibernate.proxool.pool_alias">test</prop>
				<prop key="hibernate.jdbc.batch_size">0</prop>	 
			</props>
		</property>		
	</bean>
	

	<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) 	-->
	<bean id="myTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
		<property name="sessionFactory"><ref local="mySessionFactory"/></property>
	<!-- 	<property name="dataSource"><ref local="myDataSource"/></property> -->
	</bean>

</beans>

 

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
	<class name="com.chinabank.b2c.hbm.TUser" table="t_user">
		<id name="id" column="id" type="java.lang.Integer">
			<generator class="native"><!--assigned native-->
			</generator>
		</id>
		
		<property name="name" type="java.lang.String" column="name">
		</property>
		<property name="age" type="java.lang.Integer" column="age">
		</property>
		<!--  -->
		<one-to-one name="passport" class="com.chinabank.b2c.hbm.TPassport"
			cascade="all" outer-join="true">
		</one-to-one>
	</class>
</hibernate-mapping>
 

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
	<class name="com.chinabank.b2c.hbm.TPassport" table="t_passport">
		<id name="id" column="id" type="java.lang.Integer">
			<generator class="foreign">
				<param name="property">user</param>
			</generator>
		</id>
		
		<property name="serial" type="java.lang.String" column="serial">
		</property>
		<property name="expiry" type="java.lang.Integer" column="expiry">
		</property>
		
		<one-to-one name="user" class="com.chinabank.b2c.hbm.TUser"
			constrained="true">
		</one-to-one>
	</class>
</hibernate-mapping>

 

 

javabean定义

 

 

package com.chinabank.b2c.hbm;

import java.io.Serializable;

public class TUser implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1523232529237055567L;
	public TUser(){
		
	}
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public TPassport getPassport() {
		return passport;
	}
	public void setPassport(TPassport passport) {
		this.passport = passport;
	}
	private Integer id;
	private Integer age;
	private String name;
	private TPassport passport;

}
 

 

 

package com.chinabank.b2c.hbm;

import java.io.Serializable;

public class TPassport implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7458971855517828094L;
	
	public TPassport(){
		
	}
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getSerial() {
		return serial;
	}

	public void setSerial(String serial) {
		this.serial = serial;
	}

	public Integer getExpiry() {
		return expiry;
	}

	public void setExpiry(Integer expiry) {
		this.expiry = expiry;
	}

	public TUser getUser() {
		return user;
	}

	public void setUser(TUser user) {
		this.user = user;
	}
	private Integer id;
	private String serial;
	private Integer expiry;
	private TUser user;
	
	public String toString(){
		return  this.serial+this.id+this.expiry+user.toString();
		
	}

}
 

 

 

public void cascadeT(){
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		HibernateTransactionManager manager = (HibernateTransactionManager) context.getBean("myTransactionManager");
		try {
			Session session = manager.getSessionFactory().openSession();
			TUser user = new TUser();
			user.setAge(new Integer(20));
			user.setName("Carin");

			TPassport passport = new TPassport();
			passport.setSerial("PCN759386");
			passport.setExpiry(new Integer(20150101));

			// 设置关联
			passport.setUser(user);
			user.setPassport(passport);
			Transaction tx = session.beginTransaction();
			session.save(user);
			tx.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		
	}
 

 

 

以上是最终代码。在此之前,曾遇到过这样几个问题:

 

错误1.hibernate方言适配器配置不对。

 

2012-5-22 3:22:12 net.sf.hibernate.id.TableGenerator generate
严重: could not read a hi value
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Table 'test.hibernate_unique_key' doesn't exist

 

错:<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
对:<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>

 

 

错误2. 主键没有设置为自动增长

 

警告: SQL Error: 1364, SQLState: HY000
2012-5-22 3:27:05 net.sf.hibernate.util.JDBCExceptionReporter logExceptions
严重: Field 'id' doesn't have a default value
net.sf.hibernate.exception.GenericJDBCException: could not insert: [com.chinabank.b2c.hbm.TUser]

 

`id` int(11) NOT NULL 之后加上 AUTO_INCREMENT 即:`id` int(11) NOT NULL  AUTO_INCREMENT

 

错误3. 错误的添加外键,画蛇添足

 

警告: SQL Error: 1452, SQLState: 23000
2012-5-22 3:34:40 net.sf.hibernate.util.JDBCExceptionReporter logExceptions
严重: Cannot add or update a child row: a foreign key constraint fails (`test`.`t_user`, CONSTRAINT `fk1` FOREIGN KEY (`id`) REFERENCES `t_passport` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
net.sf.hibernate.exception.GenericJDBCException: could not insert: [com.chinabank.b2c.hbm.TUser]
 

 

去掉外键
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics