a_king 2009-01-02 22:17
浏览 330
已采纳

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类都是一样的,包括数据库的结构也是一样的,但是结果为什么不一样呢?这个问题困扰我好几天了。

  • 写回答

1条回答 默认 最新

  • zxqmnzi 2009-01-03 04:25
    关注

    不是这个原因,我不知道你是怎么搞的,我按照你的要求写了一个,没出错,
    你确定你的数据库里面有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]

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)