`
cxshun
  • 浏览: 724561 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

hibernate自定义类型(2)

阅读更多

昨天讲了自定义类型中会出现异常,今天我们就来解决一下异常,文章可以看这里:http://cxshun.iteye.com/blog/1052287。试过版本3.0.1和3.6.0都出现异常,因此可以肯定应该不是3版本的问题,可能是2版本和3版本中某些东西出现比较大的变化了。这个不深究了,毕竟我们已经很少用2了。

现在讲一下解决那个问题的方法。

看到我们的EmailList类

package org.hibernate.tutorial.domain;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

public class EmailList implements UserType {

	private static final char SPLITTER = ';';
	private static final int[] TYPES = new int[] {Types.VARCHAR};
	
	public Object assemble(Serializable cached, Object owner)
			throws HibernateException {
		return null;
	}
	
	private String assemble(List emailList) {
		StringBuilder strBuf = new StringBuilder();
		for (int i = 0; i < emailList.size() - 1; i++){
			strBuf.append(emailList.get(i)).append(SPLITTER);
		}
		strBuf.append(emailList.get(emailList.size()-1));
		return strBuf.toString();
	}
	
	private List parse(String value) {
		String[] strs = value.split(";");
		List emailList = new ArrayList();
		for (int i = 0;i < strs.length; i++) {
			emailList.add(strs[i]);
		}
		return emailList;
	}

	public Object deepCopy(Object value) throws HibernateException {
		List sourceList = (List)value;
		List targetList = new ArrayList();
		targetList.add(sourceList);
		return targetList;
	}

	public Serializable disassemble(Object value) throws HibernateException {
		return null;
	}

	public boolean equals(Object x, Object y) throws HibernateException {
		if (x == y) return true;
		
		System.out.println("X:"+x+"Y:"+y);
		
		if (x != null && y != null) {
			List xList = (List)((List)x).get(0);
			List yList = (List)y;
			
			if(xList.size() != yList.size()) return false;
			
			for (int i = 0; i < xList.size(); i++) {
				String str1 = (String)xList.get(i);
				String str2 = (String)yList.get(i);
				
				if (!str1.equals(str2)) return false;
			}
			
			return true;
		}
		
		return false;
	}

	public int hashCode(Object x) throws HibernateException {
		return 0;
	}

	public boolean isMutable() {
		return false;
	}

	public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
			throws HibernateException, SQLException {
		String value = (String)Hibernate.STRING.nullSafeGet(rs, names[0]);
		if (value != null) {
			return parse(value);//用;分割字符串
		} else{
			return null;
		}
	}

	public void nullSafeSet(PreparedStatement st, Object value, int index)
			throws HibernateException, SQLException {
		System.out.println("Set Method Executed!");
		
		System.out.println("value:" + value);
		
		if (value != null){
			String str = assemble((List)((List)value).get(0));//通过;号合并list成字符串
			
			Hibernate.STRING.nullSafeSet(st, str, index);
		} else {
			Hibernate.STRING.nullSafeSet(st, value, index);
		}
	}

	public Object replace(Object original, Object target, Object owner)
			throws HibernateException {
		return null;
	}

	public Class returnedClass() {
		return List.class;
	}

	public int[] sqlTypes() {
		return TYPES;
	}
	
}

  我们修改的地方如下:

一个是euqals方法中的语句,由于强制转换出错,就先取出来再转罗。

List xList = (List)((List)x).get(0);

  另外一个是NullSafeSet方法,由于传过来的value经过了hibernate的再一次转换成list,且此list只有我们添加的list一个元素,因此可以这样做:

String str = assemble((List)((List)value).get(0));

这样修改之后我们的代码运行起来就没问题啦。

网上许多朋友都直接用相关的代码而没有经过修改,不知道为什么没问题呢,很奇怪,或者是没运行过,只是做一下记录罢了。

0
0
分享到:
评论
2 楼 cxshun 2011-05-24  
skzr.org 写道
我也做了个类型[经验][hibernate][自定义类型]hibernate 3.6.3中自定义类型,json类型的,没有遇到这样的问题。

看了下你的实现,hashCode实现有问题,不能简单的直接返回0

你既然实现了equals那么hashcode也应当有对应的逻辑。
replace也要考虑吧!?



这个我调试了一下,它在保存过程中并没有调用hashcode和replace那些方法,连assemble和disassemble也是没有调用了,不知道为什么有那个问题,还有待继续研究。好像是hibernate内部再进行了一层封装
1 楼 skzr.org 2011-05-22  
我也做了个类型[经验][hibernate][自定义类型]hibernate 3.6.3中自定义类型,json类型的,没有遇到这样的问题。

看了下你的实现,hashCode实现有问题,不能简单的直接返回0

你既然实现了equals那么hashcode也应当有对应的逻辑。
replace也要考虑吧!?

相关推荐

    Hibernate使用——自定义数据类型

    例如,使用Lombok库可以简化getter和setter的编写,而使用Hibernate Tools可以自动生成实体类和映射文件,这在处理大量自定义类型时非常有用。 总的来说,自定义数据类型是Hibernate的一个强大特性,它使我们能够...

    简要分析Java的Hibernate框架中的自定义类型

    在Java的Hibernate框架中,自定义类型是一种非常实用的功能,它允许开发者根据特定业务需求扩展Hibernate内置的数据类型。当我们发现Hibernate默认的数据类型无法满足我们存储数据的特殊要求时,例如需要处理复杂...

    hibernate + 自定义标签分页

    本例中,我们探讨的是如何结合Struts、Hibernate和自定义标签实现分页功能,这是一种常见的优化用户界面体验的技术,特别是对于数据量大的查询结果。 1. **分页原理** 分页的基本思想是将大量数据分成多个小部分,...

    用Hibernate实现领域对象的自定义字段

    2. **实现Hibernate用户类型接口**:自定义类型需要实现`org.hibernate.usertype.UserType`接口。这个接口要求我们重写一些关键方法,如`nullSafeGet()`、`nullSafeSet()`、`equals()`、`hashCode()`等,以便...

    JAVA数据类型与Hibernate的类型映射

    而在Java持久化框架Hibernate中,这些数据类型需要与数据库中的字段类型进行映射,以便正确地存储和检索数据。这篇博客主要探讨了Java数据类型如何与Hibernate的类型映射进行对应。 首先,Java的基本数据类型在...

    Java数据类型,Hibernate数据类型,标准sql数据类型之间的对应表

    此外,Hibernate还支持自定义数据类型的映射,允许开发者根据需求扩展和定制。 在实际开发中,理解这些映射关系至关重要,因为它直接影响到数据的存储和查询效率,以及数据的一致性和完整性。例如,如果错误地将...

    hibernate将本地SQL查询结果封装成对象

    query.addScalar("t2.column2", Hibernate.INTEGER); List[]&gt; objects = query.list(); ``` 以上代码会返回一个Object数组列表,每个数组元素对应一条记录,需要手动将它们转换为自定义的对象。 总结起来,...

    hibernate映射Oracle中LONG类型

    在 Hibernate 框架中,使用自定义类型映射 Oracle 中的 LONG 类型字段是一种常见的解决方案。通过实现 UserType 接口,我们可以定制 LONG 类型字段的读写操作。在本例中,我们定义了一个名为 CustomLong 的类,该类...

    Hibernate Validation自定义注解校验的实现

    Hibernate Validation自定义注解校验的实现 Hibernate Validation自定义注解校验的实现是指在Hibernate Validation框架中,使用自定义的注解来实现特定的校验逻辑。在本文中,我们将通过示例代码,详细地介绍如何...

    自定义 Hibernate Tools 的模板

    7. **扩展功能**:除了添加注释,自定义模板还可以实现其他高级功能,比如根据数据库字段类型生成特定的 Java 类型,或者为字段添加特定的注解(如 `@Column`、`@GeneratedValue`)。 8. **维护与更新**:当 ...

    hibernate杂谈

    第四部分提到了Hibernate自定义类型对象以及如何序列化为字符串存储。自定义类型是Hibernate的一个高级特性,它允许开发者为复杂类型的数据自定义映射。这一部分可能介绍了如何创建自定义类型以及如何配置Hibernate...

    JPA + Hibernate 3 CRUD操作历史审计日志的解决方案

    2. 使用Spring AOP或Hibernate事件监听机制,根据CRUD操作插入审计记录。 3. 可选地,启用Hibernate Envers模块,利用其自动化审计功能。 这个过程中,源码分析和工具选择是非常关键的。通过阅读和理解提供的源码,...

    解决Hibernate对于Date类型的数据返回结果中时分秒不对的问题

    - **自定义Type**:创建自定义的Hibernate类型,覆盖默认的日期时间处理方式,以满足特定需求。 以上就是关于"解决Hibernate对于Date类型的数据返回结果中时分秒不对的问题"的详细分析和解决方案。在实际开发中,...

    hibernate映射枚举类型

    Hibernate,作为Java中广泛使用的对象关系映射(ORM)框架,提供了一种优雅的方式来映射枚举类型到数据库。本文将深入探讨Hibernate如何映射枚举类型,并给出实际应用示例。 ### Hibernate枚举映射方式 #### 1. `@...

    张开涛 hibernate杂谈

    1.4 Hibernate自定义类型 对象---&gt;序列化为字符串 存储 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 1.5 Hibernate自定义类型 集合---&gt;字符串 存储 . . . . . . . . . . . . . . ....

    达梦Hibernate方言2.0至4.0

    例如,达梦Hibernate方言会包含对达梦特有的数据类型、函数和存储过程的适配。 对于“达梦Hibernate方言2.0至4.0”,这意味着该方言支持Hibernate框架从2.0到4.0的多个版本。每个新版本的Hibernate都可能引入新的...

    Hibernate中映射枚举类型

    在Hibernate中映射枚举类型是一个常见的需求,利用好Hibernate提供的工具和自定义映射器可以让我们更加灵活地处理不同场景下的枚举类型映射需求。通过本文介绍的方法,我们可以轻松地将枚举类型的`name`、`ordinal`...

    hibernate 调用oracle函数

    文档可能涵盖了更复杂的场景,如处理多参数函数、处理复杂返回类型、以及在事务管理中调用函数等。 总的来说,Hibernate调用Oracle函数涉及到了数据库设计、ORM框架的使用、原生SQL查询和结果映射等多个方面,熟练...

    hibernate中自动生成主键的办法

    Native策略是一种智能选择策略,Hibernate会根据当前使用的数据库类型自动选择最合适的主键生成策略,如identity、sequence或hilo。这种方式的最大优点是灵活性和兼容性,开发者无需关心底层数据库的细节,可以专注...

Global site tag (gtag.js) - Google Analytics