Java 使用hibernate 5自定义字符串序列化

Java 使用hibernate 5自定义字符串序列化,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我正在使用SpringBoot1.4.2.RELEASE和Hibernate5.0.11 我有一个实体,在这个实体上我有一个字段,我必须根据另一个字段来保持它。假设实体是这样的: package com.forty2apps.entity; import javax.persistence.Column; import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Gen

我正在使用SpringBoot1.4.2.RELEASE和Hibernate5.0.11

我有一个实体,在这个实体上我有一个字段,我必须根据另一个字段来保持它。假设实体是这样的:

package com.forty2apps.entity;

import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;

import lombok.Builder;

@Builder
@Entity
@Table(name = "max_power")
public class MaxPower implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

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

    @Column(name = "charset", nullable = false)
    private String charset;

}
我必须将有问题的_字段作为字节数组写入,以绕过表编码。我的第一次尝试是使用转换器,在
problem\u字段上使用注释
@Convert(converter=EncodedUtf8ByteArray.class)
和以下类:

package com.forty2apps.entity;

import javax.persistence.AttributeConverter;
import java.io.UnsupportedEncodingException;

public class EncodedUtf8ByteArray implements AttributeConverter<String, byte[]> {
    @Override
    public byte[] convertToDatabaseColumn(String value) {
        byte[] bytes;
        try {
            bytes = value.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        return bytes;
    }

    @Override
    public String convertToEntityAttribute(byte[] valueOnDb) {
        try {
            return new String(valueOnDb, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}
真的没有办法吗? 明确地说,我想做的是去掉硬编码的
“UTF-8”
字符串,并使用charset字段中的值;另外,我想访问hibernate将要持久化/读取的实体的整个实例


谢谢。

我觉得这个设计很有问题。我宁愿总是使用相同的编码。但无论如何,为什么不使用OO和封装:

@Embeddable
public class EncodedString {

    @Column(name = "problematic_field")
    private byte[] array;

    @Column(name = "charset", nullable = false)
    private String charset;

    @Transient
    private String value;

    private EncodedString() {
        // for Hibernate
    }

    public EncodedString(String value, String charset) {
        this.charset = charset;
        this.array = value == null ? null : value.getBytes(charset);
        this.value = value;
    }

    public String getValue() {
        if (value == null && array != null) {
            value = new String(array, charset);
        }
        return value;
    }

    public String getCharset() {
        return charset;
    }
}

我发现这个设计也有问题,但我必须制作一个java库,它的工作方式类似于传统的php应用程序,它将所有内容写入一个表中,其中表上的字符集是固定的,但应用程序使用另一个字符集上的字节来写入和读取。无论如何,我无法使用您的解决方案(我必须使用setter,hibernate抱怨循环依赖),但您使用OO和封装的想法帮助我找到了解决方案,使用了类似于您在主实体中发布的内容。非常感谢你。
@Embeddable
public class EncodedString {

    @Column(name = "problematic_field")
    private byte[] array;

    @Column(name = "charset", nullable = false)
    private String charset;

    @Transient
    private String value;

    private EncodedString() {
        // for Hibernate
    }

    public EncodedString(String value, String charset) {
        this.charset = charset;
        this.array = value == null ? null : value.getBytes(charset);
        this.value = value;
    }

    public String getValue() {
        if (value == null && array != null) {
            value = new String(array, charset);
        }
        return value;
    }

    public String getCharset() {
        return charset;
    }
}