应该是一个很简单的问题,下面的代码,无法实现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.
我都有点被 楼主整晕了···你可以先不考虑什么是生命式事务以及事务的概念 你的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]
事务都没有提交啊,
你是用的spring声明式事务吗?
查询语句有sql发出 删除没有
如果你用声明式事务
你应该检查一下是不是事务配置的有问题 只配置了查询方法的事务 没有配删除的
又是这个问题。你肯定没有加事务,你加上事务就可以了.
在Delete中加入:
[code="java"]Transaction ts = sn.beginTransaction();
sn.delete(entity);
ts.commit();[/code]
就可以了。。
[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]
尝试一下这种写法 应该没问题的
应该是spring声明式事物的问题
[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()的问题)
贴出来啊
在你的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]
不是session的问题
是你spring没有配置好 贴一下你的配置文件吧
晕 你这个是bean的注入···
你好好找找看有没有类似下面的配置 然后发上来
[code="xml"]
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
</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]
你用了spring的代理管理事务,hibernate失效
[quote]是不是Session的问题,我如果只用一个Session,来做这些查询与删除的话,是没有问题的. [/quote]
你的session是一个线程一个session。你用了多个session还不是那个session。(如果你中间不close的化)
[quote]tx = sess.beginTransaction();
//do some work
sess.delete(user);
tx.commit(); [/quote]
这样行吗??
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啊
[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了。
你好好检查检查
你那个hibernate的id是用什么方法生成的?你应该输出一下看一看那个user是不是已经真的得到了。我看了一下,你两次操作用的是同一个session,最后提交,应该是没有什么问题。
您的id 为什么是admin 用的是什么数据库,
还有 如果您的数据库中其他表 是否外键 引用这个对象实例所对应的的表
需要开启事务,并且配置在事务提交时flush和close当前session。
[code="java"]
true
true
[/code]
既然使用了spring框架,建议使用spring对hibernate的整合特性及事务管理。
LZ 先看看 任何一本有关事务的书再来写代码吧。
而不是这样子来论坛上问这种问题,
自己看的效率肯定更高,因为这是最基本的。
回答 Over 。