Hibernate: 复合主键 (Composite Key) 如何兼容 NULL值

本人博客已经迁移至 www.shangyang.me 欢迎大家访问

 

Gavin King addressed that Any Key used for Hibernate mapping should not be NULL, if any one is NULL, the whole entity should be NULL.   

reference at: http://opensource.atlassian.com/projects/hibernate/browse/HHH-177

 

现在如果我们的数据库表设计中用的是复合主键,而且复合主键中某个Key值允许为 NULL(通常维护项目的DataModel不允许修改)。这样的话,用Hibernate的<composite-key>去映射的时候,如果Hibernate如果找到某Row中的一个Key值为 NULL, 它会将整个Row映射为NULL。这样,NullPointerException会莫名其妙的抛出来.

 

解决办法如下.

创建一个 UserType 转换这个Key column的值.
1. 取值的时候,将Null 值 转为 空字符串(当然,根据自己的业务需要,可以改为其他的替代的字符串.)

2. 保存的时候,将空字符串 转换为 Null值. (这样,数据库的表的数据结构也不会受到影响)

 

UserType 定义如下.

public class KeySTRINGNull2BlankType implements UserType{
	final String _blankChar = "";
	
	public Object assemble(Serializable cached, Object owner)
			throws HibernateException {
		// TODO Auto-generated method stub
		return null;
	}

	public Object deepCopy(Object value) throws HibernateException {
		// TODO Auto-generated method stub
		String copy = new String(value.toString());
		return copy;
	}

	public Serializable disassemble(Object value) throws HibernateException {
		// TODO Auto-generated method stub
		return null;
	}

	public boolean equals(Object x, Object y) throws HibernateException {
		// TODO Auto-generated method stub
		
		if(x==y) return true;
		
		return EqualsBuilder().append(x, y).isEquals();
	}

	public int hashCode(Object x) throws HibernateException {
		// TODO Auto-generated method stub
		return new HashCodeBuilder().append(x).toHashCode();
	}

	public boolean isMutable() {
		// TODO Auto-generated method stub
		return false;
	}

	public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
			throws HibernateException, SQLException {
		// TODO Auto-generated method stub
		String variantName = (String) Hibernate.STRING.nullSafeGet(rs, names[0]);
		return variantName == null ? "" : variantName;
	}

	public void nullSafeSet(PreparedStatement st, Object value, int index)
			throws HibernateException, SQLException {
		// TODO Auto-generated method stub
		if( value.equals( _blankChar) ){
			Hibernate.STRING.nullSafeSet(st, null, index);
		}else{
			Hibernate.STRING.nullSafeSet(st, value, index);
		}
			
	}

	public Object replace(Object original, Object target, Object owner)
			throws HibernateException {
		// TODO Auto-generated method stub
		return null;
	}

	public Class returnedClass() {
		// TODO Auto-generated method stub
		return String.class;
	}

	public int[] sqlTypes() {
		// TODO Auto-generated method stub
		return new int[]{ Types.VARCHAR };
	}
}

 

配置文件如下定义 (sample)

<composite-id>
 .......
<key-property name="_field" column="FIELD" access="field" type="KeySTRINGNull2BlankType"/>
 .......
</composite-id>

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值