关于Hibernate级联数据表的存储问题(多对一)

本问题来自Struts2.1权威指南一书第19章例19.4问题,是一个关于Hibernate关联数据表存储的问题。

整个例子的目标就是建立一个WEB应用,在一个input.jsp页面上输入父亲和儿子信息,点击提交按钮,将这两个持久化对象的信息写入数据库中的两个数据表中,两个数据表分别是person(代表父亲)和son(代表儿子)。他们的关系是1(person)对N(son)

我在调试这个例程的时候遇到一个问题,就是在向数据库中写入持久化对象时出现错误提示如下:

[color=blue]Caused by: java.sql.SQLException: Unknown column 'person_id' in 'field list'[/color]

[b][color=red]经过检查具体出问题的语句是在PersonServiceImpl.java代码中的sd.save(s, son)这句(大约第在25行,就是向数据库中写入Son对象的那句)。这里说明一下sd是Son的DAO组件,具体的PersonServiceImpl.java代码见后面。
因为如果将这句注释掉,运行程序,程序可以走通,发现person表中person_id列是可以写入的。此时只是son表中没有写入任何数据。[/color][/b]
于是我检查了Person.hbm.xml、Son.hbm.xml文件,实在没有发现什么可疑之处,现将相关配置文件可能出现问题的关键部位贴出如下:
--------------------PersonServiceImpl.java代码------
[code="java"]

public class PersonServiceImpl implements PersonService
{
public void createPersonAndSon(String name , String gender
, String[] sonName , int[] sonAge)throws PersonException
{
try
{
//业务逻辑组件依赖于DAO组件,从组件工厂中取出两个DAO组件
PersonDao pd = (PersonDao)ComponentFactory.instance().getComponent("personDao");
SonDao sd = (SonDao)ComponentFactory.instance().getComponent("sonDao");
//获取Hibernate Session
Session s = HibernateUtil.sf.getCurrentSession();
Transaction tx = s.beginTransaction();
//以面向对象方式开始持久化操作
Person p = new Person();
p.setName(name);
p.setGender(gender);

pd.save(s , p);
//增加Person实体关联的Son实体
for (int i = 0 ; i < sonName.length ; i++ )
{
Son son = new Son(sonName[i] , sonAge[i]);
son.setParent(p);
sd.save(s, son);//就是这句出错了,如果注释掉这句,程序依然可以运行,只是son对象不写入数据库而已!!!
}
//提交事务

tx.commit();
}
catch (Exception e)
{
e.printStackTrace();
throw new PersonException("业务异常");
}
}
}

[/code]

---------------------Son.hbm.xml片段----------------------------------
[code="xml"]

<class name="Son" table="son">
    <id name="id" column="son_id" unsaved-value="null">
        <generator class="identity"/>
    </id>
    <property name="sonName" type="string"/>
    <property name="sonAge" type="int"/>
    <!-- 映射N:1关联实体 -->
    <many-to-one                                                   
        name="parent"                                             
        column="person_id"                                        
        class="Person"      
        cascade="all"
        not-null="true"/>
</class>

[/code]

---------------------Person.hbm.xml片段----------------------------------
[code="xml"]

<class name="Person" table="person">
    <id name="id" column="person_id" unsaved-value="null">
        <generator class="identity"/>
    </id>
    <property name="name" type="string"/>
    <property name="gender" type="string"/>
    <!-- 映射1:N关联实体 -->
    <set name="sons"  inverse="true">
        <key column="person_id"/>
        <one-to-many class="Son"/>
    </set>
</class>

[/code]

-----------------------创建数据库及表所使用的SQL语句----------------------
[code="sql"]
DROP database if exists struts2hibernate;
CREATE database struts2hibernate;
use struts2hibernate;
CREATE TABLE person(person_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
gender VARCHAR(50));
CREATE TABLE son(son_id INT AUTO_INCREMENT PRIMARY KEY,
sonName VARCHAR(50),
sonAge INT);

[/code]

别的文件就是光盘中提供的,基本没有修改。目前由于已经能够登录到数据库,并且可以修改部分数据内容,因此关于数据库连接方面配置应该没有问题,但是实在是不知道问题出在哪里了。请不吝赐教!不胜感激!

根据你的描述,person - son是1:N,那表son,就缺一个person_id,
[quote]
CREATE TABLE son(son_id INT AUTO_INCREMENT PRIMARY KEY,

sonName VARCHAR(50),

sonAge INT);

[/quote]
改成
[code="sql"]
CREATE TABLE son(son_id INT AUTO_INCREMENT PRIMARY KEY,

sonName VARCHAR(50),

sonAge INT,
person_id INT);

[/code]