You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,正确的实现方式如下:

  1. 保留isMutable()返回false:这仍是标记类型不可变的核心标识,Hibernate会基于此完成缓存、脏检查等优化操作。
  2. 修改setPropertyValue方法:不再抛出异常,改为无操作直接返回即可,因为框架调用该方法并不会实际修改对象状态。示例代码:
@Override
public void setPropertyValue(final Object component, final int property, final Object value)
    throws HibernateException {
  // 不可变类型无需处理属性设置,直接返回
}
  1. 确保组件类本身不可变:组件类的所有字段设置为final,不对外提供setter方法,从根本上保证实例创建后状态无法被修改。

内容的提问来源于stack exchange,提问作者Yury Savchuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 06:50:27