`
iwfy
  • 浏览: 36885 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

一对多的更新与删除

阅读更多

 项目中遇到多对多关联的情况,刚开始很简单的按一般的设置,在配置文件中指定了第三方表,后来发现这样更新SET的时候不太方便,也看到网上的高手们建议最好把第三方表也实例化成对象,做成两个多对一关联。

中间表
<class name="RoleMenu" table="t_role_menu" >
<many-to-one name="menuid" cascade="save-update" not-found="ignore"/>
<many-to-one name="roleid" cascade="save-update" not-found="ignore"/>
</class>
角色
<class name="Role" table="t_role">
<set name="menus" cascade="all-delete-orphan" inverse="true" batch-size="20" lazy="true">
    <key column="roleid"/>
    <one-to-many class="RoleMenu" not-found="ignore"/>
</set>
</class>

 

菜单
<class name="Menu" table="t_menu" batch-size="30">
<set name="roles" cascade="all-delete-orphan" inverse="true" lazy="true" batch-size="20">
    <key column="menuid"/>
    <one-to-many class="RoleMenu" not-found="ignore"/>
</set>
</class>

 

 根据角色动态显示菜单,因此角色跟菜单是多对多关联,利用中间类RoleMenu做成 1<--->多<--->1

这样配置起来似乎没有什么问题,但是在修改一个角色所拥有的菜单集合时却遇到了问题:

  A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance

在网上找帮助终于知道通过以下三个步骤可以解决这个问题。

1.把实体类的Set集合方法设置成private :private void setMenus(RoleMenu rm)

2.设置集合的方法成了私有的,所以要增加add方法

public void addRoleMenu(RoleMenu roleMenu){
    roleMenu.setRoleid(this);
    getMenus().add(roleMenu);
}

3.在实现类里

role.getMenus().clear(); //清除集合里的内容,hibernate会并根据cascade="all-delete-orphan"把关联的第三方记录删除

清理完原来的集合后再根据add方法重新给集合添加对象。

这样更新的问题解决了,删除又出现问题了。要删除一个角色,并需要把这个第三方对象的集合也一同删除,却碰到了因为外键关联不能删除的问题。看看配置文件应该没有什么问题。想不通为什么更新role的集合对象时就可以自动删除,到了真正删除的时候却不能删除set里的对象,于是看hibernate发出的sql语句

这是更新set集合里的对象时,先往第三方表里插入新对象,再把原来的对象删除

Hibernate: insert into t_role_menu (menuid, roleid) values (?, ?)
Hibernate: delete from t_role_menu where id=?

 

而在删除Role对象时,只发出了一条删除role的语句,删除代码:

	public void delRoles(Object[] ids) {
		Role r = null;
		for(int i = 0; i < ids.length; i++){
			r = getRole((Integer)ids[i]);
			r.getMenus().clear();//与更新时一样,清空集合对象
		}
		this.getSessionFactory()
				.getCurrentSession()
				.createQuery("delete from Role as r where r.id in (:ids)")
				.setParameterList("ids", ids)
				.executeUpdate();
	}
没有发出删除集合对象的语句
Hibernate: delete from t_role where id in (?) 
严重: Servlet.service() for servlet action threw exception 
com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails

于是把最后一条语句注释,留下清空集合的语句,看看会如何,当然成功的删除了集合里的对象,然后到MySQL命令行里删除这个role对象的记录,可以删除。看来是必须把这个role里的集合先删除了才能删除role对象,但是hibernate不先发送删除集合的命令,  难道要分成两个事务来完成删除一个role对象的动作吗?应该让hibernate先发出删除集合的sql才对。这个时候想到了session的清理缓存:

	public void delRoles(Object[] ids) {
		Role r = null;
		for(int i = 0; i < ids.length; i++){
			r = getRole((Integer)ids[i]);
			r.getMenus().clear();
			//加上这个,可以在删除1之前先把多删除,避免出现外键关联约束
			this.getSessionFactory().getCurrentSession().flush();
		}
		this.getSessionFactory()
				.getCurrentSession()
				.createQuery("delete from Role as r where r.id in (:ids)")
				.setParameterList("ids", ids)
				.executeUpdate();
	}

终于,问题解决了,可以更新删除了

先发出了删除集合对象的语句,再发出删除role对象的语句
Hibernate: delete from t_role_menu where id=?
Hibernate: delete from t_role where id in (?)

 

0
0
分享到:
评论

相关推荐

    Oracle中多表关联批量插入批量更新与批量删除操作

    这个例子中,`IN (SELECT ...)`子句用于找出与`dept`表关联的记录,并对`emp`表进行相应更新。 3. **多表关联批量删除** 批量删除操作同样考虑关联关系,如果删除一个部门,可能需要同时删除所有属于该部门的员工。...

    java一对多

    在Java中,一对多关系通常通过集合类(如List、Set或Map)来实现,这些集合类保存了与父对象相关联的多个子对象。例如,考虑一个班级(Class)和学生(Student)的例子,一个班级可以有多名学生,而每个学生只属于一...

    11_传智播客JPA详解_JPA中的一对多延迟加载与关系维护

    本教程“11_传智播客JPA详解_JPA中的一对多延迟加载与关系维护”聚焦于JPA在处理一对多关系时的延迟加载机制以及如何有效地维护这些关系。 一、JPA一对多关系 在数据库中,一对多关系意味着一个实体可以与多个其他...

    struts2+HIbernate 多对一关系 及部分删除

    本主题将深入探讨如何在Struts2与Hibernate的集成应用中实现多对一的关系以及部分删除功能。 首先,让我们理解多对一关系的概念。在数据库设计中,多对一关系意味着一个实体可以与多个另一个实体相对应,但另一个...

    博客(GreenDao一对多关系操作)的示例demo

    这个`GDOneToManyDemo`展示了如何在GreenDao中处理一对多关系,包括创建实体类、定义关系、插入、查询、更新和删除数据。理解并熟练运用这些概念,将极大地提高你在Android开发中的数据库操作效率。在实际项目中,...

    spring+struts2+hibernate 一对多增删改查

    本项目"spring+struts2+hibernate 一对多增删改查"聚焦于这三大框架在处理一对多关系时的数据操作。下面将详细阐述SSH框架在一对多关系处理中的应用和实现。 **Spring框架** Spring作为全面的轻量级应用框架,提供...

    添加、更新与删除数据

    - `DELETE`语句可以删除单条或多条满足特定条件的记录,例如: ```sql DELETE FROM student WHERE id = 3; ``` 这会删除`id`为3的记录。 - `TRUNCATE`语句则用于删除表中的所有数据,但它不会触发表上的触发器...

    hibernate 一对多 增删改差

    在Java的持久化框架Hibernate中,"一对多"(One-to-Many)关系是一种常见的实体关联类型,它代表了一个实体可以与多个其他实体相关联。本篇将详细讲解如何使用Hibernate处理这种关系,并涵盖增、删、改、查(CRUD)...

    hibernate之一对多配置demo

    【hibernate之一对多配置demo】:在Java开发中,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库与Java对象之间的交互。本教程主要关注Hibernate中的一对多关系配置,并通过XML来实现,同时也涵盖了...

    hibernate 一对多,两个实例项目

    在实际开发中,我们需要熟练掌握如何在Java代码中添加、删除和更新一对多关系的实体。例如,通过`session.save()`保存新的实体,`session.merge()`更新已存在的实体,`session.remove()`删除实体。对于集合类型的...

    ASP对数据库的添加删除更新

    在这个主题中,“ASP对数据库的添加删除更新”涉及到如何使用ASP与数据库进行交互,以实现数据管理的基本操作。 1. **数据库连接**:在ASP中,我们通常使用ADODB(ActiveX Data Objects)组件来连接和操作数据库。...

    SQL批量更新删除操作数据

    - **游标**:在存储过程中,通过游标遍历了一组值,使得能够对多个记录进行批量操作。游标提供了一种逐行处理数据集的方式,但在性能上可能不如其他方式高效。 - **存储过程**:存储过程是在服务器端预先编译好的一...

    Hibernate级联操作一对多demo

    在这个" Hibernate级联操作一对多demo "中,我们将探讨如何在一对多的关系中应用级联操作。 一对多关系是数据库中常见的关系类型,它表示一个实体(如部门)可以有多个相关实体(如员工)。在Hibernate中,这种关系...

    hibernate(一对多,多对一映射)操作

    本文将深入探讨Hibernate中的一对多和多对一映射关系,并通过一个实际的demo演示它们在增删查改操作中的应用。 首先,我们要理解什么是数据库的关联关系。在数据库设计中,我们经常遇到一种情况,即一个实体可能与...

    listview多条删除

    "listview多条删除"这个主题聚焦于ListView的一项高级功能,即如何实现长按条目后进行多条删除,并提供撤销操作。这里我们将详细探讨这个过程涉及的技术点。 1. **长按事件处理**: 在ListView中,我们需要监听...

    hadoop的web上传、下载、更新、删除和文件追加

    在实际应用中,我们可能需要通过Web界面来便捷地管理HDFS(Hadoop分布式文件系统)中的文件,这正是“hadoop的web上传、下载、更新、删除和文件追加”项目的核心内容。此项目结合了Web服务器Tomcat,实现了对HDFS的...

    Hibernate 一对多、多对一、级联、加载、反转

    1. **一对多关系**:在数据库设计中,一对多关系表示一个表中的记录可以与另一个表中的多个记录相对应。例如,考虑一个`User`表和一个`Order`表,一个用户可以有多个订单,而一个订单只能属于一个用户。在Hibernate...

    Hibernate一对多关联实例

    本文将详细解析" Hibernate一对多关联实例 ",并涵盖关联的保存(save)、删除(delete)、查询(select)和更新(update)操作。 一、一对多关联概念 在数据库设计中,一对多关联表示一个表中的记录可以与另一个表中的多个...

    JDBC批量插入 更新 删除等操作

    批量更新的原理与批量插入类似,都是通过`PreparedStatement`的`addBatch()`方法将多个更新操作加入到一个批处理队列中,然后调用`executeBatch()`方法执行这些更新操作。这种方式可以显著减少网络往返次数,提高...

    一次删除多行代码实例

    在实际开发中,多行代码的删除不仅仅是一个简单的操作,它可能涉及版本控制、代码审查以及备份策略等多个方面,确保代码的安全性和可维护性。因此,理解并掌握这种操作对于提升开发效率和保证代码质量至关重要。

Global site tag (gtag.js) - Google Analytics