我的 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);
}
}
通过实现自定义@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 |