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

从Helidon 2.5.4升级到3.2.0时遇反序列化异常求助

解决Helidon 3.2.0迁移中Hibernate反序列化URI的InvalidClassException问题

问题核心

迁移后Hibernate在merge操作时尝试深度拷贝java.net.URI对象,触发Java序列化过滤器拦截,抛出java.io.InvalidClassException: filter status: REJECTED。这是因为Helidon 3.x默认启用了更严格的序列化安全规则,而Hibernate将URI视为Serializable类型,在深度拷贝时触发了序列化流程。

解决思路

1. 将URI加入Helidon序列化允许列表

Helidon 3.x自带序列化过滤机制,需要显式允许java.net.URI类通过过滤。在配置文件(如application.yaml)中添加:

helidon:
  serialization:
    filter:
      include-classes: java.net.URI

如果需要同时允许其他类,用逗号分隔:java.net.URI,java.util.UUID

也可以通过JVM启动参数临时配置:

-Djdk.serialFilter=java.net.URI;*

2. 自定义Hibernate JavaType避免序列化拷贝

Hibernate默认对Serializable类型使用序列化方式做深度拷贝,我们可以自定义JavaType,直接通过字符串拷贝URI,绕过序列化:

步骤1:实现自定义JavaType

import org.hibernate.type.descriptor.java.MutableMutabilityPlan;
import org.hibernate.type.descriptor.java.JavaType;
import java.net.URI;

public class UriJavaType implements JavaType<URI> {
    @Override
    public Class<URI> getJavaType() {
        return URI.class;
    }

    @Override
    public MutabilityPlan<URI> getMutabilityPlan() {
        return new MutableMutabilityPlan<>() {
            @Override
            public URI deepCopy(URI value) {
                // 直接通过字符串重建URI,避免序列化
                return value != null ? URI.create(value.toString()) : null;
            }

            @Override
            public boolean isMutable() {
                return false; // URI本身是不可变类型
            }
        };
    }

    @Override
    public String toString(URI value) {
        return value != null ? value.toString() : null;
    }

    @Override
    public URI fromString(CharSequence string) {
        return string != null ? URI.create(string.toString()) : null;
    }
}

步骤2:在实体属性上使用该JavaType

@Column(name = "FILE_URI")
@Convert(converter = UriAttributeConverter.class)
@JavaType(UriJavaType.class) // 添加这一行
@Nullable
private URI fileUri;

@Nullable
@Column(name = "APPLICATION_URI")
@Convert(converter = UriAttributeConverter.class)
@JavaType(UriJavaType.class) // 添加这一行
private URI applicationUri;

3. 确保AttributeConverter正确实现

检查你的UriAttributeConverter是否正确处理URI与字符串的转换,建议开启全局自动应用:

import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import java.net.URI;

@Converter(autoApply = true) // 全局自动应用,无需每个属性加@Convert
public class UriAttributeConverter implements AttributeConverter<URI, String> {
    @Override
    public String convertToDatabaseColumn(URI attribute) {
        return attribute != null ? attribute.toString() : null;
    }

    @Override
    public URI convertToEntityAttribute(String dbData) {
        return dbData != null ? URI.create(dbData) : null;
    }
}

4. 优化Hibernate操作避免不必要的merge

如果测试中是merge操作触发的问题,可以尝试:

  • 确保实体处于托管状态后再修改属性,无需调用merge
  • 用persist或update替代merge,减少深度拷贝场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 23:14:52