当前位置: 首页 > 知识库问答 >
问题:

存储json、jsonb、hstore、xml、enum、ipaddr等失败,“列”是json类型,但表达式是字符变化类型“

程昕
2023-03-14
column "the_col" is of type json but expression is of type character varying
column "the_col" is of type json but expression is of type text

这是通过Hibernate、JPA和所有其他抽象层实现的。

PostgreSQL团队的“标准”建议是在SQL中使用强制转换。这对于使用查询生成器或ORM的人来说并不有用,特别是如果这些系统没有对诸如JSON这样的数据库类型的显式支持,所以它们是通过应用程序中的string进行映射的。

有些ORM允许实现自定义类型处理程序,但我并不想为每个ORM的每个数据类型编写自定义处理程序,例如Hibernate上的json、EclipseLink上的json、OpenJPA上的json、Hibernate上的xml等等。我在寻找一般的解决方案。

共有1个答案

诸嘉澍
2023-03-14

问题是PostgreSQL对于文本和非文本数据类型之间的转换过于严格。它将不允许隐式强制转换(在SQL中没有强制转换::)从文本类型(如textvarchar(字符变化)到文本类型(如JSONXML等)。

当调用setstring来分配参数时,PgJDBC驱动程序指定varchar的数据类型。如果列、函数参数等的数据库类型实际上不是varchartext,而是另一种类型,则会出现类型错误。这也是事实相当多的其他司机和ORM。

使用PgJDBC时,最好的选择通常是传递参数stringtype=unspecificated。这将覆盖将setstring值作为varchar传递的默认行为,而是让数据库“猜测”它们的数据类型。在几乎所有情况下,这完全符合您的要求,将字符串传递给您要存储的类型的输入验证器。

相反,您可以创建强制转换来定义特定于数据类型的强制转换,以允许在逐个类型的基础上进行强制转换,但这可能会在其他地方产生副作用。如果这样做,请不要在没有函数强制转换的情况下使用,它们将绕过类型验证并导致错误。必须对数据类型使用输入/验证函数。使用Create Cast适用于其他数据库驱动程序的用户,这些驱动程序无法停止为字符串/文本参数指定类型的驱动程序。

例如。

CREATE OR REPLACE FUNCTION json_intext(text) RETURNS json AS $$
SELECT json_in($1::cstring); 
$$ LANGUAGE SQL IMMUTABLE;

CREATE CAST (text AS json) 
WITH FUNCTION json_intext(text) AS IMPLICIT;

如果ORM允许,可以为数据类型和特定ORM实现自定义类型处理程序。当您使用与PostgreSQL类型很好地映射的本地Java类型时,而不是使用字符串时,这非常有用,但如果ORM允许您使用注释等指定类型处理程序,这也可以起作用。

实现自定义类型处理程序的方法是特定于驱动程序、语言和ORM的。下面是Java和Hibernate用于JSON的示例。

如果在Java中使用的是本机Java类型,那么可以扩展pgobject为您的类型提供PgJDBC类型映射。您可能还需要实现一个ORM特定的类型处理程序来使用pgobject,因为大多数ORM只会对它们无法识别的类型调用tostring。这是在Java和PostgreSQL之间映射复杂类型的首选方法,但也是最复杂的方法。

如果您使用string在Java中保存值,而不是使用更特定的类型,则可以调用JDBC方法setObject(integer,Object)来存储没有指定特定数据类型的字符串。JDBC驱动程序将发送字符串表示,数据库将从目标列类型或函数参数类型推断类型。

问题:

  • 将postgreSQL JSON列映射到Hibernate值类型
  • 是否可以使用JPA(EclipseLink)自定义类型?

外部:

    null

 类似资料:
  • 在我将PostgreSQL 13个数据库列标记更改为jsonb后,执行sql时抛出错误: 在使用mybatis时,我应该如何处理spring boot应用程序中的jsonb?

  • 问题内容: 在不同数据库之间进行切换时,关于包含大对象(BLOB)的hibernate映射,我有一个奇怪的问题。 上面的字段在MySQL和Oracle中创建一个字节数组字段,但是在PostreSQL中,它创建一个oid类型的字段。 现在,当我尝试访问该字段时,它在其他数据库中也能正常工作,但是在PostgreSQL中,它失败并显示以下错误 因此,我试图简单地删除“ @Lob”注释,这将解决Post

  • 我不知道我的代码发生了什么。我似乎无法弄清楚为什么数组会给我这个错误。该行是特别是 我的代码:

  • 我需要使用SpringDataJPA将实体类的两列映射为postgres中的json。阅读多个stackoverflow post和baeldung post后, 如何使用JPA将MapJSON列映射到Java对象 https://www.baeldung.com/hibernate-persist-json-object 我做了如下配置。但是,我面临错误"ERROR:列"标题"是json类型,但

  • 我想存储一个大的json散列(或内容,按您的意思来称呼它),我所说的“大”是指超过1000个键值对的东西,我不想对这个json字段进行任何搜索,我只想从数据库中检索它,并将它传递给javascript来解析它并构造一个可视化结果。

  • 这是我的实体类,映射到(9.4)中的一个表。我正在尝试将元数据存储为数据库中的类型 这是元数据类: 我使用以下迁移文件添加了列: 在中创建记录时出现此错误:错误:列“metadata”的类型为,但表达式的类型为提示:您需要重写或强制转换表达式。 这是我试图在db中持久化的请求主体: 请帮助如何转换类型为在javaSpring启动应用程序