- 浏览: 639643 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
liuche20083736:
非常好
从问题看本质: 研究TCP close_wait的内幕 -
xiaopohai85707:
优化算法与原来需求不符
过滤字符的性能调优?挤一挤还是有的 -
kmy_白衣:
生成的area图有时候 标签的数值和图标上看上去的数值不一致。 ...
OpenFlashChart2之恶心文档 -
tom&jerry:
大神,请教一个问题,按名称排序为何无效,用的2.4.3 XPA ...
深入浅出jackrabbit之十三 查询之AST和QT -
jd2bs:
改成精确匹配可以了< filter-mapping &g ...
细谈Ehcache页面缓存的使用
/**
*作者:张荣华(ahuaxuan)
*2007-04-24
*转载请注明出处及作者
*/
Hibernate在使用关联集合的时候有自己的几种类型,分别是set,list,map,bag等,而对应的hibernate实现是PersistentSet, PersistentList, PersistentBag等,几种集合类型的使用场合问题并不是今天要讨论的话题,今天要讨论的是如何在程序中使用我们自己写的集合类型,这一点
当然很多人人会质疑这样做的必要性,他们会问hibernate提供的集合类型已经够用了,为什么还要自己扩展呢? 事实上在有些情况下使用自己的集合类型是非常重要的,比如说(下面我们就以PersistentSet类举例,其他集合类情况类似)
PersistentSet类并没有序列化id,也就是说在分布式环境中如果两边的jvm版本不一样,那么没有序列化id的话,序列化一方会采用自己默认的序列化id,而反序列化一方的也会采用自己的默认的序列化id,而这两个id一般是不一样的,导致一方序列化之后另一方就无法进行正常的反序列化。当然我想应该还有其他情况需要这种扩展的,所以把它共享出来。
考虑到直接修改源代码可能和开源协议会有冲突,所以我就想到扩展自己的集合类,但是在互联网上并没有相关的信息,我在阅读了hibernate3.1的源代码之后找到了解决方案。
以下是具体实现和我的解决问题的过程:
当时想到思路之后没有办法入手,看了一下文档发现文档中并没有详细的说明,只有在一个不起眼的地方表明set节点有collectiontype这个attribute,也没有说这个collectiontype是做什么用的。报着试试的心理,我觉得应该从这个collectiontype入手,于是想到要实现自己的集合类就应该先看看hibernate源代码中PersistentSet相关代码,阅读后发现,hibernate返回什么集合类型是由对应的type类决定的,拿SetType来说
由此可以看出要返回什么集合类型确实是由对应的type类决定的,那么就是说要实现自己的集合类必须要搞清楚collectiontype的用法,也就是说必须要先处理我自己的collectiontype,而不是我自己的PersistentSet类,既然是type类,那我想就应该查看org.hibernate.type这个package里的类,看着看着先找到的是一个CustomCollectionType类:
发现要实现自己collectiontype必须要实现UserCollectionType这个接口(以上hibernate源代码中抛出的异常告诉我们实现自己的collectiontype必须要实现这个接口),
下面的就是UserCollectionType这个接口,我们只需要模范SetType来实现这个接口就可以了
步骤1:实现自己的type类
步骤2:创建自己的集合类:
步骤3:在set节点的collectiontype的attribute上指定我们的AhuaxuanPersistentSetType类了。
这样我们就成功的扩展了hibernate,并可以让我们的collectiontype指定返回我们的集合类,以上从遇到问题到产生想法再到实现一共使用了2个小时,只要思路正确,就离问题的解决不远了。
在分布式环境下使用hibernate是会遇到不少问题的,如果团队中没有精通hibernate的成员,那还是推荐ibatis。
希望这篇文章能够对遇到类似问题的同学有帮助。
作者:张荣华,未经作者同意不得随意转载!
谢谢,其实懂spring和hibernate的人还是挺多的,但是不懂的人更多。我估计我只是中级水平还不到。当然也不乏很多人懂了一点皮毛就说自己是精通,这种例子也见过很多了。
国内的IT水平要提高只有靠大家的努力,我觉得只要我们做到以下几点国内的水平一定能提高:
1 少谈大道理,多写好代码
2 不要好高骛远
3 成败在于细节
4 讲究学习方法
5 多实践
软件开发是一门工程学,不是说智商越高就越能做好的,当然智商是基础,动手能力的重要性不比智商低。
*作者:张荣华(ahuaxuan)
*2007-04-24
*转载请注明出处及作者
*/
Hibernate在使用关联集合的时候有自己的几种类型,分别是set,list,map,bag等,而对应的hibernate实现是PersistentSet, PersistentList, PersistentBag等,几种集合类型的使用场合问题并不是今天要讨论的话题,今天要讨论的是如何在程序中使用我们自己写的集合类型,这一点
当然很多人人会质疑这样做的必要性,他们会问hibernate提供的集合类型已经够用了,为什么还要自己扩展呢? 事实上在有些情况下使用自己的集合类型是非常重要的,比如说(下面我们就以PersistentSet类举例,其他集合类情况类似)
PersistentSet类并没有序列化id,也就是说在分布式环境中如果两边的jvm版本不一样,那么没有序列化id的话,序列化一方会采用自己默认的序列化id,而反序列化一方的也会采用自己的默认的序列化id,而这两个id一般是不一样的,导致一方序列化之后另一方就无法进行正常的反序列化。当然我想应该还有其他情况需要这种扩展的,所以把它共享出来。
考虑到直接修改源代码可能和开源协议会有冲突,所以我就想到扩展自己的集合类,但是在互联网上并没有相关的信息,我在阅读了hibernate3.1的源代码之后找到了解决方案。
以下是具体实现和我的解决问题的过程:
当时想到思路之后没有办法入手,看了一下文档发现文档中并没有详细的说明,只有在一个不起眼的地方表明set节点有collectiontype这个attribute,也没有说这个collectiontype是做什么用的。报着试试的心理,我觉得应该从这个collectiontype入手,于是想到要实现自己的集合类就应该先看看hibernate源代码中PersistentSet相关代码,阅读后发现,hibernate返回什么集合类型是由对应的type类决定的,拿SetType来说
public class SetType extends CollectionType { public SetType(String role, String propertyRef, boolean isEmbeddedInXML) { super(role, propertyRef, isEmbeddedInXML); } public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) { if ( session.getEntityMode()==EntityMode.DOM4J ) { return new PersistentElementHolder(session, persister, key); } else { return new PersistentSet(session); }//type类决定返回的集合类 } public Class getReturnedClass() { return java.util.Set.class; } public PersistentCollection wrap(SessionImplementor session, Object collection) { if ( session.getEntityMode()==EntityMode.DOM4J ) { return new PersistentElementHolder( session, (Element) collection ); } else { return new PersistentSet( session, (java.util.Set) collection );//type类决定返回的集合类 } } public Object instantiate() { //TODO: Might need to be a LinkedHashSet!!!!!! return new HashSet(); } }
由此可以看出要返回什么集合类型确实是由对应的type类决定的,那么就是说要实现自己的集合类必须要搞清楚collectiontype的用法,也就是说必须要先处理我自己的collectiontype,而不是我自己的PersistentSet类,既然是type类,那我想就应该查看org.hibernate.type这个package里的类,看着看着先找到的是一个CustomCollectionType类:
public class CustomCollectionType extends CollectionType { private final UserCollectionType userType; public CustomCollectionType(Class userTypeClass, String role, String foreignKeyPropertyName, boolean isEmbeddedInXML) { super(role, foreignKeyPropertyName, isEmbeddedInXML); if ( !UserCollectionType.class.isAssignableFrom(userTypeClass) ) { throw new MappingException( "Custom type does not implement UserCollectionType: " + userTypeClass.getName() ); }//也就是说要实现自己的type类就要实现usercollectiontype这个接口,看到这里,思路基本上就确定了。 try { userType = (UserCollectionType) userTypeClass.newInstance(); } catch (InstantiationException ie) { throw new MappingException( "Cannot instantiate custom type: " + userTypeClass.getName() ); } catch (IllegalAccessException iae) { throw new MappingException( "IllegalAccessException trying to instantiate custom type: " + userTypeClass.getName() ); } } public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) throws HibernateException { return userType.instantiate(session, persister); } public PersistentCollection wrap(SessionImplementor session, Object collection) { return userType.wrap(session, collection); } public Class getReturnedClass() { return userType.instantiate().getClass(); } public Object instantiate() { return userType.instantiate(); } public Iterator getElementsIterator(Object collection) { return userType.getElementsIterator(collection); } public boolean contains(Object collection, Object entity, SessionImplementor session) { return userType.contains(collection, entity); } public Object indexOf(Object collection, Object entity) { return userType.indexOf(collection, entity); } public Object replaceElements(Object original, Object target, Object owner, Map copyCache, SessionImplementor session) throws HibernateException { CollectionPersister cp = session.getFactory().getCollectionPersister( getRole() ); return userType.replaceElements(original, target, cp, owner, copyCache, session); } }
发现要实现自己collectiontype必须要实现UserCollectionType这个接口(以上hibernate源代码中抛出的异常告诉我们实现自己的collectiontype必须要实现这个接口),
下面的就是UserCollectionType这个接口,我们只需要模范SetType来实现这个接口就可以了
/** * A custom type for mapping user-written classes that implement <tt>PersistentCollection</tt> * * @see org.hibernate.collection.PersistentCollection * @author Gavin King */ public interface UserCollectionType { /** * Instantiate an uninitialized instance of the collection wrapper */ public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister) throws HibernateException; /** * Wrap an instance of a collection */ public PersistentCollection wrap(SessionImplementor session, Object collection); /** * Return an iterator over the elements of this collection - the passed collection * instance may or may not be a wrapper */ public Iterator getElementsIterator(Object collection); /** * Optional operation. Does the collection contain the entity instance? */ public boolean contains(Object collection, Object entity); /** * Optional operation. Return the index of the entity in the collection. */ public Object indexOf(Object collection, Object entity); /** * Replace the elements of a collection with the elements of another collection */ public Object replaceElements( Object original, Object target, CollectionPersister persister, Object owner, Map copyCache, SessionImplementor session) throws HibernateException; /** * Instantiate an empty instance of the "underlying" collection (not a wrapper) */ public Object instantiate(); }看到这里开始思路就步上了正轨。大家也都知道怎么做了,开始代码部分吧
步骤1:实现自己的type类
/** * * @author 张荣华 * 转载请注明出处 */ public class AhuaxuanPersistentSetType implements UserCollectionType { public PersistentCollection instantiate(SessionImplementor arg0, CollectionPersister arg1) throws HibernateException { return new AhuaxuanPersistentSet(arg0); }//这个方法也必须返回我们自己的集合类 public PersistentCollection wrap(SessionImplementor arg0, Object arg1) { if (arg0.getEntityMode() == EntityMode.DOM4J) { return new PersistentElementHolder(arg0, (Element) arg1); } else { return new AhuaxuanPersistentSet(arg0, (Set) arg1); }//这个方法也必须返回我们自己的集合类 }//这个方法是最重要的,告诉hibernate我们是返回什么样的具体类型,这里我们指定的是自己的集合类,之所以这样写是因为hibernate自己的type类是这样实现的 //而其他需要实现的方法是拷自hibernate自己的type类,基本可以忽略 }
步骤2:创建自己的集合类:
public class AhuaxuanPersistentSet extends PersistentSet { //这个类其实是继承自hibernate自己的PersistentSet,因为我们只需要下面这个//serialVersionUID而已 /** * * @author 张荣华 * 转载请注明出处 */ private static final long serialVersionUID = 3821652119009257031L; public AhuaxuanPersistentSet(SessionImplementor session) { super(session); } public AhuaxuanPersistentSet(SessionImplementor session, Set set) { super(session, set); } public AhuaxuanPersistentSet() { } }
步骤3:在set节点的collectiontype的attribute上指定我们的AhuaxuanPersistentSetType类了。
<set collection-type=" AhuaxuanPersistentSetType" name="aa" inverse="true" cascade="save-update" > <key> <column name="aa" precision="10" scale="0"/> </key> <one-to-many class="test.User"/> </set>
这样我们就成功的扩展了hibernate,并可以让我们的collectiontype指定返回我们的集合类,以上从遇到问题到产生想法再到实现一共使用了2个小时,只要思路正确,就离问题的解决不远了。
在分布式环境下使用hibernate是会遇到不少问题的,如果团队中没有精通hibernate的成员,那还是推荐ibatis。
希望这篇文章能够对遇到类似问题的同学有帮助。
作者:张荣华,未经作者同意不得随意转载!
评论
4 楼
somebody
2007-09-20
赞一个。
不错的分享。
不错的分享。
3 楼
cm4ever
2007-07-31
提交给hibernate组织没?
2 楼
ahuaxuan
2007-07-26
fuwang 写道
很多公司都在用spring+hibernate,可是真正懂的人非常之少,大部分人都是照着写增删改查,经常是出了问题而不自知,导致垃圾项目一个接着一个。要是做的是电信和金融等方面的项目,真让人胆颤心惊啊。
像楼主这样爱研究又愿意分享的人不多了,希望楼主在技术上继续精进,只有你这样的人多了,国内的IT水平才能真正提高啊。
像楼主这样爱研究又愿意分享的人不多了,希望楼主在技术上继续精进,只有你这样的人多了,国内的IT水平才能真正提高啊。
谢谢,其实懂spring和hibernate的人还是挺多的,但是不懂的人更多。我估计我只是中级水平还不到。当然也不乏很多人懂了一点皮毛就说自己是精通,这种例子也见过很多了。
国内的IT水平要提高只有靠大家的努力,我觉得只要我们做到以下几点国内的水平一定能提高:
1 少谈大道理,多写好代码
2 不要好高骛远
3 成败在于细节
4 讲究学习方法
5 多实践
软件开发是一门工程学,不是说智商越高就越能做好的,当然智商是基础,动手能力的重要性不比智商低。
1 楼
fuwang
2007-07-23
很多公司都在用spring+hibernate,可是真正懂的人非常之少,大部分人都是照着写增删改查,经常是出了问题而不自知,导致垃圾项目一个接着一个。要是做的是电信和金融等方面的项目,真让人胆颤心惊啊。
像楼主这样爱研究又愿意分享的人不多了,希望楼主在技术上继续精进,只有你这样的人多了,国内的IT水平才能真正提高啊。
像楼主这样爱研究又愿意分享的人不多了,希望楼主在技术上继续精进,只有你这样的人多了,国内的IT水平才能真正提高啊。
发表评论
-
过滤字符的性能调优?挤一挤还是有的
2010-05-29 05:54 3610/* *auth ... -
Master-Slave,Spring,Hibernate,故事曲折离奇,情结跌宕起伏
2009-02-05 13:49 8684/** *作者:张荣华 *日期 ... -
弃成见,反省,并重新认识struts.i18n.encoding
2008-12-24 15:42 3882[size=medium]之前和大家讨论了struts2.0中 ... -
关键字:查询,事务,粒度
2008-08-22 17:05 5139[size=medium]/** *作者: ... -
看看mina和memcached的联姻(适合不同语言客户端,高并发?)
2008-07-21 17:06 7984[size=medium]/** * 作者:张荣华 * 日 ... -
如何解决mysql的master-slave模式中ReplicationDriver的使用问题
2008-06-19 18:23 8220/** * 作者:张荣华 * 日期:2008-6-19 ... -
别装了,难道你们不想把properties直接注入到object中去(spring-plugin)?
2008-04-09 18:01 3651[size=small]/** *作者:张荣华(ahuaxu ... -
用jamon来监控你的sql执行效率
2008-02-25 15:48 3716/** *作者:张荣华 *日期:2008-2-25 ... -
java同msn的通信,大家想想用途吧
2007-11-24 17:14 2514程序员的生活真是单调,除了编程还是编程,工作日 ... -
EAI企业应用集成场景及解决方案
2007-09-21 18:21 3155/** *作者:张荣华(ahuaxuan) *2007-9 ... -
quartz和应用的集群问题
2007-08-21 18:36 12818之前看到很多关于quartz的讨论,尤其是关于quar ... -
优化程序之前,可用Jamon来监测你的Spring应用
2007-08-14 18:14 8125/** *作者:张荣华(ahuaxuan) *2007-8-1 ... -
请问责任链真的是一种设计模式吗
2007-07-26 18:12 9414坛子上讨论设计模式的也挺多的,但是关于这个责任链模式还没有人提 ... -
把ActiveMQ的控制台整合到你的web程序中
2007-07-19 12:06 8830在使用ActiveMQ的时候把ActiveMQ的控制台整 ... -
设计模式之:解剖观察者模式
2007-07-17 16:12 6868[size=9] 论坛上很多人都 ... -
java邮件:在简单和复杂之间的方案
2007-07-11 18:07 7585/** *作者:张荣华(ahuaxu ... -
强强连手, 在模板中分页,看Freemarker和displaytag的结合
2007-07-09 09:22 6927/** *作者:张荣华(ahuaxuan) *2007-0 ... -
解惑:在spring+hibernate中,只读事务是如何被优化的。
2007-06-28 18:22 7622/** *作者:张荣华(ahuaxuan) *2007- ... -
让webwork零配置 第二章(实现)(实例已放出,大家可以下载运行)
2007-06-25 09:23 5709/** *作者:张荣华(ahuaxuan) *2007-0 ... -
让webwork2零配置,第一章(主贴再次更新)
2007-06-18 15:41 13380/** *作者:张荣华(ahuaxuan) *2007-0 ...
相关推荐
在Hibernate中,我们可以使用集合类(如List、Set、Map等)来映射这些关系。例如,一个学生可以有多次成绩记录,这就构成了一个学生到成绩的映射关系,通常我们使用Map来表示这种关系,因为Map能确保每个学生都有...
2. **javassist.jar**:Hibernate使用Javassist库来动态生成字节码,实现运行时对类的增强,比如添加getter和setter方法,实现序列化等。这对于ORM框架来说是必不可少的,因为我们需要在不修改源代码的情况下,为...
在给定的文档中,我们看到一个例子,展示了如何在 Hibernate 中配置一个具有集合属性的实体类 `Person`,以及如何通过映射文件启用延迟加载。`Person` 类拥有一个 `Set<Address>` 类型的 `addresses` 属性,表示个人...
### Hibernate使用指南精要 #### 一、简介与入门 **1.1 引言** Hibernate 是一个开源的对象关系映射 (ORM) 框架,它为 Java 应用程序提供了一种将 Java 对象映射到关系型数据库表中的机制。本章节将详细介绍如何...
3. **实体类与表映射**:Hibernate使用注解或XML文件(hbm.xml)将Java类映射到数据库表,如@Table、@Column等注解,定义了类与表、属性与列的关系。 4. **Session接口**:在Hibernate中,Session是与数据库交互的...
Hibernate利用这些集合类优化数据处理和查询。 6. **commons-beanutils.jar**:Apache Commons BeanUtils库,提供了一系列工具类,方便操作JavaBeans。在Hibernate中,这些工具可能用于属性的自动绑定和转换。 7. ...
3. **commons-collections-3.1.jar**:Apache Commons Collections提供了各种实用的集合框架扩展,包括更复杂的集合操作,这在处理数据映射时非常有用。 4. **antlr-2.7.6.jar**:ANTLR是一个强大的解析器生成器,...
5. **commons-collections.jar**:Apache Commons Collections提供了许多Java集合类的扩展和增强,帮助Hibernate执行高级数据处理和转换。 6. **commons-beanutils.jar**:Apache Commons BeanUtils提供了一系列...
这个集合是为了便于学习和使用Hibernate 3.x框架而准备的,适用于初学者和开发者,确保他们能够快速搭建开发环境。 **描述解析:** 描述中提到,这个集合包含了马士兵老师在VeryCD.com上分享的Hibernate教程中所...
在Java的Hibernate框架中,集合类数据结构的映射是将Java的集合类型(如Set、Map、List和数组)映射到数据库的关系模型,以便于在对象关系映射(ORM)中管理和操作数据。以下是关于如何进行集合映射的详细教程: 一...
通过阅读文档,开发者可以了解到如何定义和管理Bean,如何使用AOP实现切面逻辑,以及如何集成Hibernate等ORM框架进行数据库操作。 Hibernate3 API文档: Hibernate是一个对象关系映射(ORM)框架,它简化了Java应用...
2. **javassist.jar**: Hibernate使用了Javaassist库来动态生成代理类和字节码,以实现对象和数据库表之间的映射。在运行时,Hibernate通过这个库对Java类进行修改和增强。 3. **jta.jar**: Java Transaction API ...
综上所述,"spring集合hibernate多数据切换"这个知识点涉及到Spring框架的IoC容器、AOP、事务管理,以及Hibernate的SessionFactory配置等多个方面。通过理解并实践这些内容,开发者能够构建出更灵活、可扩展的企业级...
1. **commons-collections-3.1.jar**:Apache Commons Collections库提供了对集合框架的扩展,包括各种实用工具类和算法,如队列、堆、图等,对于数据处理非常有用。 2. **hibernate-jpa-2.0-api-1.0.0.Final.jar**...
16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体(Returning multiple entities) 16.1.5. 返回非受管实体(Returning non-managed entities) 16.1.6. 处理继承(Handling ...
例如,创建实体类、编写映射文件(XML或使用注解)、配置Hibernate的主配置文件(hibernate.cfg.xml),并利用SessionFactory和Session对象进行数据的增删改查操作。同时,Hibernate的Criteria、HQL(Hibernate ...
【标题】:“Hibernate、Spring和Struts工作原理及使用理由” 【内容】: Hibernate是一个流行的Java持久化框架,它的核心工作原理主要包括以下步骤: 1. **读取并解析配置文件**:Hibernate通过读取hibernate....
4. **commons-collections-3.1.jar**: Apache Commons Collections是Java集合框架的一个扩展库,提供了一系列实用工具类和算法,用于操作集合。Hibernate使用这个库来增强其功能,如排序、查找等。 5. **log4j-...
此外,文档中还可能包含了对Hibernate架构的深入分析,比如它的插件架构、服务加载机制以及如何扩展Hibernate来适应特定需求的详细说明。其中对于Java EE应用服务器的集成部分,涉及了Hibernate如何与J2EE容器进行...