Java Hibernate将Postgres数据库中的现有整数[]转换为字符串[](bytea)

Java Hibernate将Postgres数据库中的现有整数[]转换为字符串[](bytea),java,spring,postgresql,hibernate,Java,Spring,Postgresql,Hibernate,我正在使用Spring、Hibernate和Postgres。 在我的一个模型课程中,我有: @Entity class SomeData { private Long dataId; private String name; private Integer[] data; } 它已经被使用,我在数据库中有上述格式的数据 “数据”字段是bytea(在phppgadmin中可见)类型,保存在db中的示例值之一是: ��ur[Ljava.lang.Integer;�����

我正在使用Spring、Hibernate和Postgres。 在我的一个模型课程中,我有:

@Entity
class SomeData {
    private Long dataId;
    private String name;
    private Integer[] data;
}
它已经被使用,我在数据库中有上述格式的数据

“数据”字段是bytea(在phppgadmin中可见)类型,保存在db中的示例值之一是:

��ur[Ljava.lang.Integer;������xpsr...
问题是,现在我需要将模型更改为

String[] data;
但当我这样做时,Hibernate无法读取这些数据,因为它的类型为Integer


我的问题-是否可以以某种方式将这些整数数组对象转换为字符串数组对象?使用一些数据库工具,sql查询或Hibernate?

您需要编写一个转换算法来运行一次。比如:

Connection c = ((SessionImplementor)entitymanager).connection();
boolean oldstate = c.getAutoCommit();
c.setAutoCommit(false);
Statement s = c.createStatement();
PreparedStatement ps = c.prepareStatement("UPDATE my_table SET data = ? WHERE id = ?");
ResultSet rs = s.executeQuery("SELECT id, data FROM my_table");
ByteArrayInputStream bais;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectInputStream ois;
ObjectOutputStream oos = new ObjectOutputStream(baos);
while (rs.next()) {
    long id = rs.getLong(1);
    byte[] bdata = rs.getBytes(2);
    bais = new ByteArrayInputStream(bdata);
    ois = new ObjectInputStream(bais);
    Integer[] olddata = (Integer[]) ois.readObject();
    String[] newdata = new String[olddata.length];
    for (int i = 0; i < olddata.length; i++) {
        Integer din = olddata[i];
        String dout = null;
        if (din != null) {
            dout = din.toString();
        }
        newdata[i] = dout;
    }
    oos.writeObject(newdata);
    oos.flush();
    ps.setLong(1, id);
    ps.setBytes(2, baos.toByteArray());
    baos.reset();
}
c.commit();
c.setAutoCommit(oldstate);
Connection c=((SessionImplementor)entitymanager.Connection();
布尔oldstate=c.getAutoCommit();
c、 设置自动提交(错误);
语句s=c.createStatement();
PreparedStatement ps=c.prepareStatement(“更新我的表格集数据=?其中id=?”;
ResultSet rs=s.executeQuery(“选择id,从my_表中选择数据”);
ByteArrayInputStream bais;
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
目的输入流ois;
ObjectOutputStream oos=新的ObjectOutputStream(BAS);
while(rs.next()){
long id=rs.getLong(1);
字节[]bdata=rs.getBytes(2);
bais=新的ByteArrayInputStream(bdata);
ois=新的ObjectInputStream(BAI);
整数[]旧数据=(整数[])ois.readObject();
String[]newdata=新字符串[olddata.length];
对于(int i=0;i
如果您想通过Hibernate进行转换,您需要一个辅助列,或者您必须将其更改为
Object[]
,运行转换,然后将其更改为
String[]
,但这对产品更新不方便,也不高效,因为您在Hibernate中会经历很多层的验证和转换


但是,如果您选择在数据库本身内部使用数组类型,我目前建议使用一个独立的模块来支持它。我们没有无法使用它的测试用例,但如果您能找到任何需要修复的测试用例,这将有助于获得批准。

也许这会有所帮助?或者在您的
setData()
方法中,包含将
Integer[]
转换为
String[]
的逻辑。问题是,为什么首先要存储序列化的Java对象?这几乎总是个坏主意。最好将其存储为Postgres中的
int[]
text[]
——这样您也可以使用SQL操作data@user3626048您是否使用某种迁移工具来更改模式(例如liquibase、flyway等)?另外,您是否坚持新类型为
String[]
?(在
列表上的f.ex.
@ElementCollection
?)user3626048如果您没有这样的工具,您只能使用手工编写和执行的自定义脚本更改模式,而不是进行适当的规范化。您需要一些java代码来从表中读取序列化的值,您没有其他选项了。-是的,规范化有时需要更多的表,但这只会使您的结构更加清晰,而不是复杂。你目前的情况相当复杂,因为缺乏正常化。