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));
这样修改之后我们的代码运行起来就没问题啦。
网上许多朋友都直接用相关的代码而没有经过修改,不知道为什么没问题呢,很奇怪,或者是没运行过,只是做一下记录罢了。
1 楼 skzr.org 2011-05-22 我也做了个类型[经验][hibernate][自定义类型]hibernate 3.6.3中自定义类型,json类型的,没有遇到这样的问题。