Hibernate 6 Postgres bytea、Oracle varchar2 在 JPA 实体中的映射

问题描述 投票:0回答:1

我的 jpa 实体中有一个列,它应该映射到 Postgres 中的 bytea 和 oracle 中的 varchar2(1024)。

@Column(name="users")
private String users;

我正在使用 hibernate 6.2.28.Final jars 以及 spring-orm 6.x 和 JDK 21。请帮助我。

我尝试了如下所示的自定义@Convert,这适用于 postgres。但它也在oracle中存储字节数组数据。它应该将 bytea 数据存储在 postgres 中,将普通数据存储在 oracle 中。


import java.nio.charset.StandardCharsets;

import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;

@Converter(autoApply = false)
public class StringByteArrayConverter implements AttributeConverter<String, byte[]> {

    @Override
    public byte[] convertToDatabaseColumn(String attribute) {
        if (attribute == null) {
            return null;
        }
        return attribute.getBytes(StandardCharsets.UTF_8);
    }

    @Override
    public String convertToEntityAttribute(byte[] dbData) {
        if (dbData == null) {
            return null;
        }
        return new String (dbData, StandardCharsets.UTF_8);
    }
}
postgresql oracle hibernate jpa hibernate-6.x
1个回答
0
投票

通过实现自定义@JavaType解决了问题。

import java.nio.charset.StandardCharsets;
import java.sql.Types;

import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.StringJavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;


public class CustomStringJavaType extends StringJavaType {

    
    @Override
    public JdbcType getRecommendedJdbcType(JdbcTypeIndicators stdIndicators) {
        if (stdIndicators.getDialect() instanceof PostgreSQLDialect){
            TypeConfiguration typeConfiguration = stdIndicators.getTypeConfiguration();
            JdbcTypeRegistry registry = typeConfiguration.getJdbcTypeRegistry();
            return registry.getDescriptor(Types.BINARY); // Maps to bytea in PostgreSQL
        }
        return super.getRecommendedJdbcType( stdIndicators );
    }

    
    public <X> X unwrap(String value, Class<X> type, WrapperOptions options) {
        if (byte[].class.isAssignableFrom(type)) {
            return value != null ? (X) value.getBytes(StandardCharsets.UTF_8) : null;
        }
        return super.unwrap(value, type, options);
    }

    
    public <X> String wrap(X value, WrapperOptions options) {
        if (value instanceof byte[]){
            return value != null ? new String((byte[]) value, StandardCharsets.UTF_8) : null;
        }
        return super.wrap(value, options);
    }

}

在实体中使用了如下所示的 CustomStringJavaType。

@Column(name = "users")
@JavaType(value= CustomStringJavaType.class)
private String users;

这是列类型和它要映射到的数据库。

Postgres MySQL 甲骨文 MsSQL
拜茶 blob、varchar 巴巴 文本、nvarchar
© www.soinside.com 2019 - 2024. All rights reserved.