为了节省篇幅,映射文件中一些不重要的信息都被省略
<hibernate-mapping>
<class name="TClassMeta" table="T_CLASS_META">
<id name="classMetaId" type="java.lang.Long" column="CLASS_META_ID">
</id>
<set name="tfieldMetas" cascade="none">
<key column="CLASS_META_ID"/>
<one-to-many class="com.ebao.pub.metadata.data.TFieldMeta"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<joined-subclass
name="PdsType"
extends="TClassMeta"
table="T_CLASS_META_PDS">
<key column="CLASS_META_ID" />
<list name="pdsAttributes" inverse="true" cascade="none">
<key column="CLASS_META_ID"/>
<index column="DISPLAY_ORDER"/>
<one-to-many class="PdsAttribute"/>
</list>
</joined-subclass>
</hibernate-mapping>
<hibernate-mapping>
<class name="TFieldMeta" table="T_FIELD_META">
<id name="fieldMetaId" type="java.lang.Long" column="FIELD_META_ID">
</id>
<many-to-one name="tclassMeta" column="CLASS_META_ID" />
</class>
</hibernate-mapping>
<hibernate-mapping>
<joined-subclass
name="PdsAttribute"
extends="TFieldMeta"
table="T_FIELD_META_PDS" lazy="false">
<key column="FIELD_META_ID" />
<property
name="displayOrder"
type="java.lang.Integer"
column="DISPLAY_ORDER" />
<property
name="classMetaId"
type="java.lang.Long"
column="CLASS_META_ID"/>
</joined-subclass>
</hibernate-mapping>
TClassMeta ------------- TFieldMeta
/|\ /|\
| |
PdsType ------------- PdsAttribute
- PdsType继承TClassMeta
- PdsAttribute继承TFieldMeta
- TClassMeta与TFieldMeta是一对多的关系
- PdsType与PdsAttribute是一对多的关系
- 继承映射的策略是:table per subclass(每个子类一个表)
- 删除一个PdsAttribute
这是最容易引起问题的地方,而且在目前来讲,还没有任何文档涉及这种复杂情况下的删除,正确的操作应该有下面两种:
- 若在父类TClassMeta的映射文件中指定tfieldMetas字段的属性cascade="none",且子类PdsType的pdsAttributes字段的属性cascade="none",则在删除是直接对pdsAttribute删除就可以了,实例代码:
PdsAttributeDelegate.remove(AttributeId);
-
- 若上面两个属性中任一个设置为非"none"的话,都要在删除pdsAttribute时,分别从TClassMeta(tfieldMetas)与PdsType(attributes)的集合中显式地删除pdsAttribute对象,否则会抛出net.sf.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade(remove deleted object from associations)异常,示例代码如下:
TClassMeta tclassMeta = pdsAttribute.getTclassMeta();
Set tfieldMetas = tclassMeta.getTfieldMetas();
tfieldMetas.remove(TFieldMetaDelegate.load(AttributeId));
Long pdsTypeId = tclassMeta.getClassMetaId();
PdsType pdsType = PdsTypeDelegate.load(pdsTypeId);
List attributes = pdsType.getPdsAttributes();
attributes.remove(pdsAttribute);
int displayOrder = pdsAttribute.getDisplayOrder().intValue();
for (Iterator iter = attributes.iterator(); iter.hasNext();) {
PdsAttribute tmp = (PdsAttribute) iter.next();
int tmpDisplayOrder = tmp.getDisplayOrder().intValue();
if (displayOrder < tmpDisplayOrder) {
tmp.setDisplayOrder(new Integer(tmpDisplayOrder - 1));
}
}
PdsAttributeDelegate.remove(AttributeId);
- 其实上面的映射方法是值得商榷的,可以删除PdsType类中维护对PdsAttribute类的一对多引用(因为父类中已经维护了这个关系,只是映射的集合类型是list而已),也就是删除上面的PdsType映射文件的list映射内容.若没有这个映射,则示例代码如下:
PdsType pdsType = (PdsType) pdsAttribute.getTclassMeta();
Set attributes = pdsType.getTfieldMetas();
attributes.remove(pdsAttribute);
int displayOrder = pdsAttribute.getDisplayOrder().intValue();
for (Iterator iter = attributes.iterator(); iter.hasNext();) {
PdsAttribute tmp = (PdsAttribute) iter.next();
int tmpDisplayOrder = tmp.getDisplayOrder().intValue();
if (displayOrder < tmpDisplayOrder) {
tmp.setDisplayOrder(new Integer(tmpDisplayOrder - 1));
}
}
PdsAttributeDelegate.remove(AttributeId);
- 继承映射的子类可以重复父类的映射字段,但最好不要这样做.
- 关于list映射的问题,需要分外添加一个顺序字段,类型应该只要是数字类型就可以了,下面假设这个字段名为:POSITION
一般开发时都是使用set,简单一点,若使用list也有不少暗礁
- POSITION一定要从0开始,若从1开始,则它会把映射出来的list对象的0设置的对象为null.推而广之,若POSITION是从2开始,则映射出来的集合对象的0,1位置的对象都是null,可能有人说,没是,我取的时候做一下检测就可以,这是不对的,若我们调用list.size()方法,出来的结果就是错误,而且还会引起更大的错误
- POSITION一定要是连续的,否则取出来的list对象会把空缺位置的对象设置为null
- POSITION不能有重复的数据,如果有相同,或者2个以上重复的序号的话,最后hibernate只会取出来的一条记录,具体是那条记录,要看产生的sql语句了,默认是物理位置的第一条
- 在进行删除操作时,hibernate会自动更新这个POSITION字段,比如现在的序号有0,1,2,3,4. 若删除2,则hibernate会自动把后面的3,4分别改为2,3.当然自己手动更新也是可以的.
注意:这个自动更新,可能会有问题,只有在集合类中删除这个对象才可以,若是单独删除这个对象,是不会自动更新POSITION的
- 关于cascade的属性设置,我个人认为在关系很复杂的对象图中,应该谨慎设置这个属性,少用all的值
- hibernate(2.1.6版本)自带文档的9.8小节,说得比较含糊,没有经过实践操作,很难理解它的重要性
- oreilly:Hibernate: A Developer's Notebook的5.4小节
<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://wiki.ebaosh.com/confluence/pages/viewpage.action?pageId=2668"
dc:identifier="http://wiki.ebaosh.com/confluence/pages/viewpage.action?pageId=2668"
dc:title="hibernate复杂映射关系下的删除操作和list类型映射的注意点"
trackback:ping="http://wiki.ebaosh.com/confluence/rpc/trackback/2668" />
</rdf:RDF>
--><!--
Root decorator: all decisions about how a page is to be decorated via the
inline decoration begins here.
--><!--
Switch based upon the context. However, for now, just delegate to a decorator
identified directly by the context.
-->
分享到:
相关推荐
此外,自定义对象的映射是Hibernate映射中的一个重要部分。通过在实体类上使用@Entity注解,并使用@Id注解指定主键字段,可以将一个Java类映射到数据库的一张表。字段则通过@Column注解来指定列名和属性,如长度、...
Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用 Java 对象来操作数据库,消除了直接编写 SQL 的需要。在 Hibernate 中,映射关系是将数据库表与 Java 类之间的关联方式,使得对象模型可以与关系...
**标题:“Hibernate List集合映射”** 在Java的持久化框架Hibernate中,集合映射是将数据库中的表与Java对象的集合属性关联的过程。...理解和熟练掌握List映射的配置和操作,对于进行高效、稳定的ORM编程至关重要。
综上所述,Hibernate映射集合属性List是通过注解或XML配置来实现的,它可以简化数据库操作,使代码更专注于业务逻辑。自动创建表功能则进一步简化了开发流程,而集合操作和懒加载策略则优化了性能。在实际项目中,...
在IT行业中,数据库管理和对象关系映射(ORM)框架是至关重要的部分,特别是对于Java开发者而言,Hibernate是一个广泛使用的ORM工具。本主题将深入探讨Hibernate集合映射与关联关系,包括"student与Score的Map集合...
【标题】"Hibernate教程20_关系映射案例三"主要涵盖了在Hibernate框架中如何进行对象关系映射(ORM)的实践,特别是针对复杂关系的处理。在这个教程中,我们可能会学习到以下关键知识点: 1. **关系映射**:...
在实际应用中,我们可以通过Hibernate提供的API来添加、删除和查找多对多关系。例如,向`Student`添加一门`Course`,可以使用`addCourse(Course course)`方法;删除则通过`removeCourse(Course course)`方法。 六、...
### Hibernate关联映射总结 #### 一、基础知识 在探讨Hibernate中的关联映射之前,我们需要先理解几个基本概念,这将有助于我们更好地...理解这些基本概念和映射方式对于有效使用Hibernate进行数据库操作至关重要。
本教程将详细讲解Hibernate中的关联关系映射配置,帮助你理解和掌握如何在Hibernate中设置不同类型的关联。 一、一对一(One-to-One)关联 在现实世界中,两个实体之间可能存在一对一的关系,例如一个人只有一个...
本文将深入探讨“hibernate关联映射实例”中的关键知识点,包括一对多、多对多和继承映射,这些都是Hibernate中至关重要的概念。 1. **一对多关联映射**: 在现实世界中,一个实体可能会与多个其他实体相关联,...
本文将深入探讨Hibernate中的四种主要集合映射类型:Set、List、Array和Map,以及它们在实际开发中的应用场景和配置。 一、Set集合映射 Set集合映射是最常见的映射类型,它不允许重复元素。在Hibernate中,Set通常...
在Java世界中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据。本篇将详细探讨Hibernate中的映射关系,主要包括实体之间的一对一、一对多、...
总之,Hibernate集合映射是对象关系映射的重要组成部分,理解并熟练掌握各种映射类型、级联操作、缓存策略等,将有助于我们在实际开发中更高效、更灵活地处理数据库与Java对象之间的关系。在实践中,不断调整和优化...
**hibernate映射与查询** Hibernate 是一个流行的 Java 应用程序开发框架,它提供了一个持久层解决方案,简化了数据库操作。对于初学者来说,理解 Hibernate 的映射和查询机制是至关重要的,因为它们构成了 ...
Hibernate 是一个开源的Java ORM(Object-Relational Mapping)框架,它通过提供一种对象-关系映射机制,使得开发者可以使用面向对象的方式来操作数据库,从而避免了传统的JDBC繁琐的数据库操作。 ### 数组映射原理...
总结,Hibernate的关联关系映射是其强大的功能之一,通过合理的配置,我们可以轻松地在Java对象和数据库表之间建立复杂的关系,实现对象的持久化。理解并熟练运用这些映射方式,对于提升Java应用的数据管理效率至关...
本文将深入探讨Hibernate如何实现多对多关联映射,并通过实际例子解析相关配置和操作。 一、多对多关联概述 在数据库设计中,多对多关联表示两个表之间的关系,如学生和课程的关系,一个学生可以选修多门课程,而...
标题“Hibernate映射树形结构”指的是如何用Hibernate来存储和操作具有层级关系的数据。 1. **单表映射策略**: Hibernate可以使用单个表来存储树形结构,通过一个自增的`id`字段以及一个表示父节点的`parent_id`...
Hibernate容器映射技术(Set、List、Map)
在 Hibernate 中,集合映射是指将 Java 集合类型与数据库表之间的映射关系。常见的集合映射类型有 Set、List、Array、Map 和 Bag 等,每种类型都有其特点和应用场景。 Set 集合映射 Set 集合是 Hibernate 中基础的...