ustcfxx
2009-03-18 12:16 阅读 241
已采纳

Hibernate 删除记录的问题

应该是一个很简单的问题,下面的代码,无法实现user的删除,在日志输出中,只能看到findById()对应的Select SQL,delete函数对应的SQL看不到,应该是此句没有执行。
另外,如果直接用一个Session去做这些事的话,是可以实现删除的。
原因是什么?
请指教。

代码如下:
[code="java"]TbUserDAO userDAO = new TbUserDAO();
TbUser user = userDAO.findById("admin");
userDAO.delete(user);[/code][/code]

其中,TbUser是实体类,TbUserDAO是DAO类,findByID与delelte函数代码如下:
[code="java"] public TbUser findById(java.lang.String id) {
log.debug("getting TbUser instance with id: " + id);
try {
TbUser instance = (TbUser) getSession().get(
"org.user.model.TbUser", id);
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}[/code]

[code="java"] public void delete(TbUser persistentInstance) {
log.debug("deleting TbUser instance");
try {
getSession().delete(persistentInstance);
log.debug("delete successful");
} catch (RuntimeException re) {
log.error("delete failed", re);
throw re;
}
}[/code]

[b]问题补充:[/b]
[code="java"]Transaction tx = HibernateSessionFactory.
getSession().beginTransaction();
TbUserDAO userDAO = new TbUserDAO();
TbUser user = userDAO.findById("admin");
userDAO.delete(user);
tx.commit();[/code]这样提交以后,仍然没有删除掉该数据.是Session的问题吗?
[b]问题补充:[/b]
to [Zoran],你的办法不行!仍然没有删除那条记录!
[b]问题补充:[/b]
to [Zoran] 我这是一个Web项目,用的Struts2+Hibernate+Spring的架构,但是没有用Spring来管理Hibernate.不知道你说的spring声明式事务是什么意思?如果是你所说的问题,具体如何改正与操作.
[b]问题补充:[/b]
[code="java"]

private static final ThreadLocal threadLocal = new ThreadLocal();
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();

    if (session == null || !session.isOpen()) {
        if (sessionFactory == null) {
            rebuildSessionFactory();
        }
        session = (sessionFactory != null) ? sessionFactory.openSession()
                : null;
        threadLocal.set(session);
    }

    return session;
}[/code]

HibernateSessionFactory的代码以及实体类的代码都是由MyEclipse的Hibernate插件自动生成的.我觉得这里可能没什么问题.是不是Session的问题,我如果只用一个Session,来做这些查询与删除的话,是没有问题的.
[b]问题补充:[/b]
to [Zoran], 我没有用Spring来管理Hibernate.Spring的配置如下:

applicationContext.xml
[code="xml"]<?xml version="1.0" encoding="UTF-8"?>
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="queryTextAction" class="org.xtwh.query.action.QueryTextAction" />
<bean id="queryMainAction" class="org.xtwh.query.action.QueryMainAction" />
<bean id="queryResultAction" class="org.xtwh.query.action.QueryResultAction" />
<bean id="queryResultListAction" class="org.xtwh.query.action.QueryResultListAction" />


<bean id="jsonPluginAction" class="test.JsonPluginAction" />
<bean id="testAction" class="test.TestAction"/>

[/code]
[b]问题补充:[/b]
to [Zoran] 我没有用Spring来管理Hibernate啊.

[b]问题补充:[/b]
to [Zoran],没有,这就是我全部的Spring了,我现在对Spring还不怎么了解,我想也不一定要用Spring来做Hibernate的管理吧.
另外,就上面这些代码来说,我觉得没有任何问题啊.为什么不能Delete?
[b]问题补充:[/b]
另外,实际是,下面的代码,可以实现我要的删除操作:
[code="java"] Session session = HibernateSessionFactory.getSession();
Transaction tx = null;
try {
tx = session.beginTransaction(); TbUser user = (TbUser)session.load(TbUser.class, "admin");
session.delete(user);

} catch(Exception e) {

    } finally {            
                        tx.commit();
        session.close();
    }[/code]

[b]问题补充:[/b]
to [yuanyangaas]
[quote]你用了spring的代理管理事务,hibernate失效[/quote]
你说的是什么意思?能详细点吗?
[b]问题补充:[/b]
getSession() 代码如下:它实际上还是调用了HibernateSessionFactory这个类的getSession函数.那个函数我在上面已经帖出来了,应该没有问题.
[code="java"]public Session getSession() {
return HibernateSessionFactory.getSession();
}[/code]
[b]问题补充:[/b]
to [all] 问题成功解决.谢谢大家的帮助,下面简单总结一下.
首先要说的是,问题都不像大家列举的那样.
具体原因是在Hibernate启动过程中出现了如下的Error:
[code="txt"]ERRORmain- org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:155) Unsuccessful: alter table BSK.TB_CANCEL_INFO add constraint FK99DEA302D9E10358 foreign key (ORDERID) references BSK.TB_ORDER
ERRORmain- org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:156) ORA-02275: 此表中已经存在这样的引用约束条件[/code]
类似这样的Error有9个,主要是由于外键约束引起的.(当时我以为这些错误没有什么影响,就没有在意.)
但是,我的Hibernate的映射是由MyEclipse自带的Hibernate插件自动生成的,不知道为什么会出现这种错误.在网上找了很久,没有找到相关的解决办法.
最后,我将
[code="xml"]update[/code]
改成了:
[code="xml"]create[/code]
重新根据映射文件生成数据库,再将"create"改成"update",上面的错误消息.
这样关于数据库更新操作不能执行的问题就解决了.
最后要说的是Hibernate的Session管理方法,一般来说都是ThreadLocal的,所以在一个线程中使用getSession获取到的是同一个Session.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

19条回答 默认 最新

  • 已采纳
    weixin_42514193 小女昆玲 2009-03-19 11:37

    我都有点被 楼主整晕了···你可以先不考虑什么是生命式事务以及事务的概念 你的delete ,findById。。都可以使用下面的方法进行持久化操作 先用这种写法实现了再说吧 这是Hibernate官方推荐的写法

    [code="java"]
    public TbUser findById(java.lang.String id) {
    Session sess =HibernateSessionFactory .openSession();
    Transaction tx;
    log.debug("getting TbUser instance with id: " + id);
    try {
    tx = sess.beginTransaction();
    TbUser instance = (TbUser) sess.get(
    "org.user.model.TbUser", id);
    tx.commit();
    return instance;
    }catch(Exception e) {
    if (tx!=null) tx.rollback();
    throw e;
    }finally {
    sess.close();
    }

    [/code]

    [code="java"]
    public void delete(TbUser persistentInstance) {
    Session sess =HibernateSessionFactory .openSession();
    Transaction tx;
    log.debug("deleting TbUser instance");
    try {
    sess.delete(persistentInstance);
    log.debug("delete successful");
    tx.commit();
    }catch (Exception e) {

    if (tx!=null) tx.rollback();

    throw e;

    }finally {

    sess.close();
    }

    [/code]

    点赞 评论 复制链接分享
  • wanghaolovezlq wanghaolovezlq 2009-03-18 12:54

    事务都没有提交啊,

    点赞 评论 复制链接分享
  • weixin_42514193 小女昆玲 2009-03-18 12:57

    你是用的spring声明式事务吗?

    查询语句有sql发出 删除没有

    如果你用声明式事务
    你应该检查一下是不是事务配置的有问题 只配置了查询方法的事务 没有配删除的

    点赞 评论 复制链接分享
  • qiao88 qiao88 2009-03-18 13:07

    又是这个问题。你肯定没有加事务,你加上事务就可以了.

    点赞 评论 复制链接分享
  • itanger itanger 2009-03-18 18:22

    在Delete中加入:
    [code="java"]Transaction ts = sn.beginTransaction();
    sn.delete(entity);
    ts.commit();[/code]
    就可以了。。

    点赞 评论 复制链接分享
  • weixin_42514193 小女昆玲 2009-03-18 22:53

    [code="java"]
    Session sess =HibernateSessionFactory .openSession();
    Transaction tx;
    try {
    tx = sess.beginTransaction();
    //do some work
    TbUserDAO userDAO = new TbUserDAO();

    TbUser user = userDAO.findById("admin");

    userDAO.delete(user);

    tx.commit();
    }
    catch (Exception e) {
    if (tx!=null) tx.rollback();
    throw e;
    }
    finally {
    sess.close();
    [/code]

    尝试一下这种写法 应该没问题的

    点赞 评论 复制链接分享
  • zy_pub zy_pub 2009-03-19 00:15

    应该是spring声明式事物的问题

    点赞 评论 复制链接分享
  • qiao88 qiao88 2009-03-19 10:43

    [quote]Transaction tx = HibernateSessionFactory.

    getSession().beginTransaction();

    TbUserDAO userDAO = new TbUserDAO();

    TbUser user = userDAO.findById("admin");

    userDAO.delete(user);

    tx.commit(); [/quote]
    这样都不行啊。
    那肯定是Transaction tx = HibernateSessionFactory.

    getSession().beginTransaction();

    这里的问题啊。
    你把HibernateSessionFactory的代码贴出来啊。(很有肯能是你的getSession()的问题)
    贴出来啊

    点赞 评论 复制链接分享
  • weixin_42514193 小女昆玲 2009-03-19 10:51

    在你的DAO里面我没有看到任何关于事务的代码 然后你查询有可以正常执行
    很明显你们项目应该是通过spring的声明式事务来管理事务的
    麻烦把你们spring的配置文件贴上来 看一下 主要看一下你们的事务是怎么配置的 问题应该在这

    不好意思 之前发你的代码有点小问题 但是思路没问题 你用下面的代码做一个delete的单元测试 问题已经很明显了
    [code="java"]
    Session sess =HibernateSessionFactory .openSession();
    Transaction tx;
    try {
    tx = sess.beginTransaction();
    //do some work

     sess.delete(user);  
      tx.commit();
    

    }
    catch (Exception e) {
    if (tx!=null) tx.rollback();
    throw e;
    }
    finally {
    sess.close();
    [/code]

    点赞 评论 复制链接分享
  • weixin_42514193 小女昆玲 2009-03-19 10:55

    不是session的问题
    是你spring没有配置好 贴一下你的配置文件吧

    点赞 评论 复制链接分享
  • weixin_42514193 小女昆玲 2009-03-19 11:01

    晕 你这个是bean的注入···
    你好好找找看有没有类似下面的配置 然后发上来
    [code="xml"]
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">




    tx:attributes





        </tx:attributes>
    </tx:advice>
    
    
    <aop:config>
        <aop:pointcut id="allManagerMethod"
            expression="execution(* com.javaeye.manager.*.*(..))" />
        <aop:advisor pointcut-ref="allManagerMethod"
            advice-ref="txAdvice" />
    </aop:config>
    

    [/code]

    点赞 评论 复制链接分享
  • yuanyangaas yuanyangaas 2009-03-19 11:03

    你用了spring的代理管理事务,hibernate失效

    点赞 评论 复制链接分享
  • qiao88 qiao88 2009-03-19 11:07

    [quote]是不是Session的问题,我如果只用一个Session,来做这些查询与删除的话,是没有问题的. [/quote]

    你的session是一个线程一个session。你用了多个session还不是那个session。(如果你中间不close的化)
    [quote]tx = sess.beginTransaction();

    //do some work

    sess.delete(user);     
     tx.commit();   [/quote]
    

    这样行吗??

    点赞 评论 复制链接分享
  • qiao88 qiao88 2009-03-19 11:16

    public void delete(TbUser persistentInstance) {

    log.debug("deleting TbUser instance");

    try {

    [size=xx-small][color=red] getSession().[/color][/size]delete(persistentInstance);

    log.debug("delete successful");

    } catch (RuntimeException re) {

    log.error("delete failed", re);

    throw re;

    }

    }

    把你的这个方法贴出来,是不是在这个方法中把session给close啊

    点赞 评论 复制链接分享
  • qiao88 qiao88 2009-03-19 12:46

    [quote]另外,实际是,下面的代码,可以实现我要的删除操作:
    Java代码
    Session session = HibernateSessionFactory.getSession();

    Transaction tx = null;

    try {

    tx = session.beginTransaction(); TbUser user = (TbUser)session.load(TbUser.class, "admin");

    session.delete(user);

    } catch(Exception e) {

    } finally {

    tx.commit();

    session.close();

    } [/quote]这个可以成功说明下面的问题

    出现你的问题有两方面的问题
    1:你的多个session是不同的线程(这个概率不大,你好像是在一个线程中操作的)
    2:你在你程序中把session给close了。
    你好好检查检查

    点赞 评论 复制链接分享
  • ablong ablong 2009-03-19 13:17

    你那个hibernate的id是用什么方法生成的?你应该输出一下看一看那个user是不是已经真的得到了。我看了一下,你两次操作用的是同一个session,最后提交,应该是没有什么问题。

    点赞 评论 复制链接分享
  • mafangling mafangling 2009-03-19 22:50

    您的id 为什么是admin 用的是什么数据库,
    还有 如果您的数据库中其他表 是否外键 引用这个对象实例所对应的的表

    点赞 评论 复制链接分享
  • u012453006 eeonj 2009-03-20 09:56

    需要开启事务,并且配置在事务提交时flush和close当前session。
    [code="java"]
    true
    true
    [/code]

    既然使用了spring框架,建议使用spring对hibernate的整合特性及事务管理。

    点赞 评论 复制链接分享
  • iampurse iampurse 2009-03-20 12:08

    LZ 先看看 任何一本有关事务的书再来写代码吧。

    而不是这样子来论坛上问这种问题,

    自己看的效率肯定更高,因为这是最基本的。

    回答 Over 。

    点赞 评论 复制链接分享

相关推荐