one-to-many 的级联删除 把我折磨惨了.
首先 我一直想避免先把 对象查找出来 然后再删除.
所以我就准备先删除子表(就是many一段),然后再删除父表(就是one一端的数据),但是这是不可以的....
关于网上什么的 cascade='all' 我都试过了,也米有效果.如上的不成功,所以我就直接使用
getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session)
})
如上的方法直接 用session来删除 也是不可以的.
然后我又使用网上 广为流传的 hql 删除级联的 写法 也是不正确的.
举个例子
A one-to-many B
String hql="DELETE FROM A a, B b WHERE b.a.id=a.id and a.id=?"
或是
String hql="DELETE a FROM A a, B b WHERE b.a.id=a.id and a.id=?"
都是不可以的..此处我注明下 我用的是 MySql ssh架构...
有人说是 事务的原因我把我的事务处理也贴出来
<tx:method name="get*" read-only="true" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>+
请各位高手 根据自己的经验来 搞下..
我觉得主要解决的目标就是 不用先查出对象就可以根据hql进行删除.
首先 我一直想避免先把 对象查找出来 然后再删除.
所以我就准备先删除子表(就是many一段),然后再删除父表(就是one一端的数据),但是这是不可以的....
关于网上什么的 cascade='all' 我都试过了,也米有效果.如上的不成功,所以我就直接使用
getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session)
})
如上的方法直接 用session来删除 也是不可以的.
然后我又使用网上 广为流传的 hql 删除级联的 写法 也是不正确的.
举个例子
A one-to-many B
String hql="DELETE FROM A a, B b WHERE b.a.id=a.id and a.id=?"
或是
String hql="DELETE a FROM A a, B b WHERE b.a.id=a.id and a.id=?"
都是不可以的..此处我注明下 我用的是 MySql ssh架构...
有人说是 事务的原因我把我的事务处理也贴出来
<tx:method name="get*" read-only="true" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>+
请各位高手 根据自己的经验来 搞下..
我觉得主要解决的目标就是 不用先查出对象就可以根据hql进行删除.
import java.util.Set;import org.springframework.stereotype.Component;import com.hhd.zxg.bean.Category;@Component(value = "categoryDao")
public class CategoryDaoImpl extends DaoImpl implements CategoryDao { @Override
public void delete(Category c) { Category category = (Category) hibernateTemplate.load(Category.class, c.getId());
if (category.getParent() == null) {
deleteParent(category);
} else {
List<?> list = hibernateTemplate
.find("from Product p where p.category.id=" + category.getId()); hibernateTemplate.flush();
hibernateTemplate.clear();
hibernateTemplate.deleteAll(list);
hibernateTemplate.delete(category);
} }
/**
* 有孩子
*/
public void deleteParent(Category c) { Set<Category> children = c.getChildren(); if (children.size() == 0) {
hibernateTemplate.delete(c);
} else {
for (Category category : children) {
List<?> list = hibernateTemplate
.find("from Product p where p.category.id="
+ category.getId());
hibernateTemplate.flush();
hibernateTemplate.clear();
hibernateTemplate.deleteAll(list);
hibernateTemplate.delete(category);
} c.setChildren(null);
hibernateTemplate.delete(c);
} }}
利用hql
这里大家都是推荐的 先查出这些数据,然后删除.
而我想避免这种效率浪费,直接删除,不要再查询了.
这是主要目标,请大家看清问题......
例如 hql="delete from A a where a.id=?"
这样是么....
大哥您这么写过么,没写过没成功的最好别说出来,误导人啊.....
@ManyToOne(fetch = FetchType.LAZY)
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
貌似是这个,但是规范好像是 都是one的一段放弃关系的维护.
这位老兄 根据你的思路 还是要查询,
而且就算按照你的 思路来的话, 可以在查询单端的时候join fetch 出多端,
然后直接删除单端,附带多端也会删除.
这个方法是可行的,比你的方法少了次数据库查询