标签:blog http java os io 2014 for re
今天遇到的问题是在 VisitRecord
编辑保存之后,MedicineComment
中的 Medicine
属性就变成 null 了。经过简单的调查之后发现,在做更新操作时,起作用的并不是 UserType
的 nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
方法,而是 Object replace(Object original, Object target, Object owner)
方法。
不得不说,Hibernate 的文档 坑爹地压根没提到这一点。好在这个方法的 API 其实很容易理解。具体做法看一下代码吧。
public class MedicineUserType implements UserType { @Override public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { String value = (String) StringType.INSTANCE.get(rs, names[0], session); return MedicineRepository.getInstance().findByName(value); } @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { if (value == null) StringType.INSTANCE.set(st, null, index, session); else StringType.INSTANCE.set(st, ((Medicine) value).getName(), index, session); } @Override public Object replace(Object original, Object target, Object owner) throws HibernateException { return original; }
有若干不相关的方法被忽略。nullSafeSet
方法的用法在文档和不少文章里都有介绍,不再赘述。来看 replace
方法。其实很简单,先看一下 Java doc 中的描述:
During merge, replace the existing (target) value in the entity we are merging to with a new (original) value from the detached entity we are merging. For immutable objects, or null values, it is safe to simply return the first parameter. For mutable objects, it is safe to return a copy of the first parameter. For objects with component values, it might make sense to recursively replace component values.
根据文档的描述,只需直接返回第一个参数就行。因为 Medicine
是不变的对象。
关于 Hibernate User Type,这篇文章写的很详细
后记:看来光看 Reference 还是不够的,有些问题官方 Reference 也不一定会说,即便是像 Hibernate 的项目。
DSR 系统开发记录(2014年7月25日):Hibernate User Type 更新操作,布布扣,bubuko.com
DSR 系统开发记录(2014年7月25日):Hibernate User Type 更新操作
标签:blog http java os io 2014 for re
原文地址:http://my.oschina.net/lifany/blog/294819