spring+hibernate实现持久化

我在用spring和hibernate写一个bbs的时候遇到一个问题
其中有三个JAVABean,
一个是
//论坛的留言
public class Bbs {
private int bbsId;
private String bbsTitle;
private String bbsContent;
private Board board;//论坛版块
private User author;
......省略get,set方法
}
bbs.hbm.xml如下
<?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" >




seq_bbs_id







一个JAVABEAN是
//论坛的版块
public class Board {
private int boardId;
......省略其他属性
private Set bbs = new HashSet();//表示留言,是一对多的关系
......省略set,get方法
}
board.hbm.xml如下
<?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" >




seq_board_id









还有一个是用户类
public class User {
private int userId;
......省略其他属性
private Set bbs = new HashSet();
......省略get,set方法
}
user.hbm.xml如下
<?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" >




seq_user_id


......省略其他属性配置





我的spring的配置文件applicationContext.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<!-- database -->
class="org.springframework.jdbc.datasource.DriverManagerDataSource">

oracle.jdbc.driver.OracleDriver


jdbc:oracle:thin:@localhost:1521:univser


bbs


bbs

<!-- define Hibernate SessionFactory -->







org.hibernate.dialect.Oracle9Dialect

true




com/foxconn/hz/bbs/entity/user/user.hbm.xml
com/foxconn/hz/bbs/entity/board/board.hbm.xml
com/foxconn/hz/bbs/entity/bbs/bbs.hbm.xml
















有三个接口userDao,bbsDao,boardDao,分别实现的方法是
userDao.getUserById(int id){
return (User)getHibernateTemplate().get(User.Class,id);
}
boardDao.getBoardById(int id){
return (Board)getHibernateTemplate().get(Board.Class,id);
}
bbsDao.addBbs(Bbs bbs){
getHibernateTemplate().save(bbs);
}
我又写了一个测试方法
//实现对bbs对象的持久化
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("applicationContext.xml");
BoardDao boardDao = (BoardDao)ctx.getBean("boardDao");
BbsDao bbsDao = (BbsDao)ctx.getBean("bbsDao");
UserDao userDao = (UserDao)ctx.getBean("userDao");

Board board = boardDao.getBoardById(0);
User user = userDao.getUserById(0);
System.out.println(board);//执行正确
System.out.println(user);//执行正确

Bbs bbs = new Bbs();
bbs.setAuthor(user);
bbs.setBoard(board);
bbsDao.addBbs(bbs);
}
}
如果我只将user对象set到bbs中,然后持久化bbs,程序运行正确
当我将board对象set到bbs中的时候,就出错,报错信息是
Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: com.foxconn.hz.bbs.entity.board.Board; nested exception is org.hibernate.TransientObjectException: com.foxconn.hz.bbs.entity.board.Board
Caused by: org.hibernate.TransientObjectException: com.foxconn.hz.bbs.entity.board.Board
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:216)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:108)
at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:221)
at org.hibernate.type.TypeFactory.findDirty(TypeFactory.java:476)
at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:2803)
at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:467)
at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:190)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:113)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:195)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:373)
at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:632)
at com.foxconn.hz.bbs.service.imp.BbsBiz.addBbs(BbsBiz.java:27)
at com.foxconn.hz.bbs.service.imp.Test.main(Test.java:31)
从错误提示看,是set到bbs对象中的board对象的一个非持久态的对象,导致bbs不能实现持久化,我用getHibernateTemplate().get(Board.Class,id)得到的不是一个持久态的对象吗?还有我不理解的就是set user对象的时候却没有错误,我看了好几遍User类和Board类都是一样的,包括数据库的结构也是一样的,但是结果为什么不一样呢?这个问题困扰我好几天了。

不是这个原因,我不知道你是怎么搞的,我按照你的要求写了一个,没出错,
你确定你的数据库里面有board id为0 的这个数据?
下面是你的代码,我稍微的修改了下
applicactionContxtn.xml
[code="java"]

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

<!-- database -->
<bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource">
    <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="root" />
</bean>

<!-- define Hibernate SessionFactory  -->
<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
        <ref bean="dataSource" />
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">
                org.hibernate.dialect.MySQLDialect
            </prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
    <property name="mappingResources">
        <list>
            <value>com/bbs/model/user.hbm.xml</value>
            <value>com/bbs/model/bbs.hbm.xml</value>
            <value>com/bbs/model/board.hbm.xml</value>
        </list>
    </property>
</bean>
<!-- end db -->
<bean id="userDao" class="com.bbs.model.dao.UserDao">
    <property name="sessionFactory">
        <ref local="sessionFactory" />
    </property>
</bean>

<bean id="boardDao" class="com.bbs.model.dao.BoardDao">
    <property name="sessionFactory">
        <ref local="sessionFactory" />
    </property>
</bean>
<bean id="bbsDao" class="com.bbs.model.dao.BbsDao">
    <property name="sessionFactory">
        <ref local="sessionFactory" />
    </property>
</bean>

[/code]
bbs.hbm.xml
[code="java"]
<?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" >

dynamic-insert="true" dynamic-update="true">



column="title" />

    <property name="content" type="string" not-null="true"
        column="content" />
    <many-to-one name="author" column="uid"
        class="com.bbs.model.User" />
    <many-to-one name="board" column="bid"
        class="com.bbs.model.Board" />
</class>


[/code]
user.hbm.xml
[code="java"]
<?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" >

dynamic-update="true">





    <set name="bbs" inverse="true">
        <key column="uid" />
        <one-to-many class="com.bbs.model.Bbs" />
    </set>
</class>

[/code]
board.hbm.xml
[code="java"]
<?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" >

<class name="com.bbs.model.Board" table="board" lazy="false"
    dynamic-update="true" dynamic-insert="true">

    <id name="id" column="id">
        <generator class="native" />
    </id>

    <property name="name" type="java.lang.String" not-null="true">
        <column name="name" />
    </property>

    <set name="bbs" inverse="true">
        <key column="bid" />
        <one-to-many class="com.bbs.model.Bbs" />
    </set>

</class>

[/code]
[code="java"]
bbs.java
private int id;
private String title;
private String content;
private User author;
private Board board;

user.java
private int id;
private String name;
private Set bbs = new HashSet();

board.java
private int id;
private String name;
private Set bbs = new HashSet();

Test.java
package com.bbs.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.bbs.model.Bbs;
import com.bbs.model.Board;
import com.bbs.model.User;
import com.bbs.model.dao.BbsDao;
import com.bbs.model.dao.BoardDao;
import com.bbs.model.dao.UserDao;

public class Test {

/**
 * @param args
 * @throws Exception
 */
public static void main(String[] args) throws Exception {
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    BoardDao boardDao = (BoardDao)ctx.getBean("boardDao"); 
      BbsDao bbsDao = (BbsDao)ctx.getBean("bbsDao");
      UserDao userDao = (UserDao)ctx.getBean("userDao");

      Board board = boardDao.findById(1);
      User user = userDao.findById(1);
      System.out.println(board);//执行正确
      System.out.println(user);//执行正确
      System.out.println(user.getName());
      System.out.println(board.getName());
      Bbs bbs = new Bbs();
      bbs.setTitle("测试");
      bbs.setContent("测试");
      bbs.setAuthor(user);
      bbs.setBoard(board);
      bbsDao.save(bbs); 
}

}

[/code]
输出结果为:
[code="java"]
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select board0_.id as id2_0_, board0_.name as name2_0_ from board board0_ where board0_.id=?
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_ from user user0_ where user0_.id=?
com.bbs.model.Board@2798e7
com.bbs.model.User@e34726
灌水人
灌水
Hibernate: insert into bbs (title, content, uid, bid) values (?, ?, ?, ?)

[/code]