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));

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

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

你可能感兴趣的:(sql,Hibernate,Blog,ITeye)