昨天讲了自定义类型中会出现异常,今天我们就来解决一下异常,文章可以看这里: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));
这样修改之后我们的代码运行起来就没问题啦。
网上许多朋友都直接用相关的代码而没有经过修改,不知道为什么没问题呢,很奇怪,或者是没运行过,只是做一下记录罢了。