Hibernate 5.6.12调用不可变CompositeUserType的setPropertyValue方法异常问题
Hibernate升级后不可变CompositeUserType的setPropertyValue被调用问题
问题背景
我实现了不可变的CompositeUserType,重写了以下方法:
setPropertyValue方法
@Override public void setPropertyValue(final Object component, final int property, final Object value) throws HibernateException { throw new HibernateException("Object is immutable."); }
isMutable方法
@Override public boolean isMutable() { return false; }
在Hibernate 5.6.12版本前该实现运行正常,但升级后,即使isMutable()返回false,setPropertyValue方法仍被调用。查阅变更日志未找到合理解释,请问:
- 版本相关变更是什么?
- 新版本中如何正确使用不可变类的
CompositeUserType?
版本变更说明
Hibernate 5.6.x后期版本及更高版本中,对CompositeUserType的不可变处理逻辑做了调整:
- 旧版本中,当
isMutable()返回false时,Hibernate会完全跳过setPropertyValue的调用; - 新版本里,即使标记为不可变,Hibernate在结果集映射、实体加载属性填充等场景下,仍会尝试调用
setPropertyValue,不再单纯依赖isMutable()来跳过该方法。这是框架内部优化属性绑定流程后,统一了可变与不可变类型的处理路径导致的。
正确实现方式
针对不可变的CompositeUserType,正确的实现方式如下:
- 保留
isMutable()返回false:这仍是标记类型不可变的核心标识,Hibernate会基于此完成缓存、脏检查等优化操作。 - 修改
setPropertyValue方法:不再抛出异常,改为无操作直接返回即可,因为框架调用该方法并不会实际修改对象状态。示例代码:
@Override public void setPropertyValue(final Object component, final int property, final Object value) throws HibernateException { // 不可变类型无需处理属性设置,直接返回 }
- 确保组件类本身不可变:组件类的所有字段设置为
final,不对外提供setter方法,从根本上保证实例创建后状态无法被修改。
内容的提问来源于stack exchange,提问作者Yury Savchuk
相关产品推荐
相关产品推荐

