当使用PostgreSQL将数据存储在一个绳状验证类型的字段,如xml
,json
,jsonb
,xml
,ltree
,等等,所述INSERT
或UPDATE
失败等错误:
column "the_col" is of type json but expression is of type character varying
Run Code Online (Sandbox Code Playgroud)
... 要么
column "the_col" is of type json but expression is of type text
Run Code Online (Sandbox Code Playgroud)
为什么?我能做些什么呢?
我正在使用JDBC(PgJDBC).
这通过Hibernate,JPA和各种其他抽象层发生.
PostgreSQL团队的"标准"建议是CAST
在SQL中使用a .这对于使用查询生成器或ORM的人来说没有用,特别是如果这些系统没有对数据库类型的明确支持json
,因此它们通过String
应用程序进行映射.
一些ORM允许实现自定义类型处理程序,但我真的不想为每个ORM编写每个数据类型的自定义处理程序,例如Hibernate上的json,EclipseLink上的json,OpenJPA上的json,Hibernate上的xml,...用于编写通用自定义类型处理程序的JPA2 SPI没有.我正在寻找一个通用的解决方案.
我正在关注以下网址中提到的示例? 将postgreSQL JSON列映射到Hibernate值类型
但总是得到以下异常:
Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: 2000
at org.hibernate.dialect.TypeNames.get(TypeNames.java:76)
at org.hibernate.dialect.TypeNames.get(TypeNames.java:99)
at org.hibernate.dialect.Dialect.getTypeName(Dialect.java:310)
at org.hibernate.mapping.Column.getSqlType(Column.java:226)
at org.hibernate.mapping.Table.validateColumns(Table.java:369)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1305)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:512)
Run Code Online (Sandbox Code Playgroud)
我使用TomEE作为服务器.并尝试将Json正文存储到postgresql列.我试图将实体pojos映射到postgres数据类型结构.
知道可能是什么问题吗?或者是否有更好的技术来处理这种情况?请指出我的来源.
用于创建实体表的脚本是:
CREATE TABLE historyentity
(
id character varying(255) NOT NULL,
userid character varying(255),
lastchanged timestamp without time zone,
type character varying(255),
history json [],
CONSTRAINT historyentity_pkey PRIMARY KEY (id),
CONSTRAINT historyentity_userid_fkey FOREIGN KEY (userid)
REFERENCES userentity (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
) …
Run Code Online (Sandbox Code Playgroud) 特别是我对使用PostgreSQLs json
类型感兴趣.
问题的核心似乎是Eclipselink中没有内部映射来json
键入.因此,使用一种天真的方法:
@Column(name = "json", columnDefinition = "json")
public String getJson() {
return json;
}
Run Code Online (Sandbox Code Playgroud)
...并尝试插入一个对象,我得到一个例外:
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "json" is of type json but expression is of type character varying
Run Code Online (Sandbox Code Playgroud)
我觉得很公平.
通过EclipseLink文档,似乎适用的自定义(转换映射,本机查询,转换器)依赖于由支持的映射(数字,日期,字符串等)组成的数据,因此使得使用它变得非常尴尬供应商特定类型.
这是如此令人沮丧的主要原因是json
posgresql 中的类型表达与text/varchar相同,我相信(目前,但不是永远)只是该类型的别名 - 因此驱动程序能够传输这个,这只是我的验证规则.
就解决方案而言,我不介意丢失可移植性(在数据库不可知和使用供应商特定类型方面),但只是想要一个允许我json
在普通JPA实体上使用类型作为属性并保留所有它习惯的其他行为(模式生成,合并,持久化,事务代码
我用JPA 2.1 Converter
将PostgreSQL转换hstore
为Map<String, String>
.但我没有找到适用于EclipseLink和Hibernate等不同JPA提供程序的通用方法.所以我需要为每个JPA提供程序编写不同的转换器.
以下是使用EclipseLink和Hibernate的不同转换器的示例. https://github.com/phstudy/jpa-converter-sample
对于不同的JPA提供商,是否有通用的方法?
简短版本是:如何jsonb
使用Spring Data Rest PATCH方法修补Postgres 字段中包含的JSON对象?
这是长版本,请考虑以下实体:
@Entity
@Table(name = "examples")
public class Example {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String jsonobject;
@JsonRawValue
public String getJsonobject() {
return jsonobject == null ? null : jsonobject;
}
public void setJsonobject(JsonNode jsonobject) {
this.jsonobject = jsonobject == null ? null : jsonobject.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
jsonobject
是Postgres类型jsonb
.这些getter/setter是为这里提到的Spring Data Rest序列化/反序列化它的方法.我们还尝试给该字段提供自己的类型,如这些答案中所述.
我们的目标是使用Spring Data Rest修补此字段包含的JSON对象.
例如:
GET /examples/1
{
"id": 1,
"jsonobject": {
"foo": {"bar": …
Run Code Online (Sandbox Code Playgroud) 我的架构中有一个Postgres'json'列.这是我的代码中的列映射:
def my_col = column[Option[String]]("my_col")
Run Code Online (Sandbox Code Playgroud)
哪个不起作用,插入时得到的堆栈跟踪说:
列"my_col"的类型为json,但表达式的类型为字符变化
我也试过这个:
def my_col = column[Option[String]]("my_col", O.SqlType("json"))
Run Code Online (Sandbox Code Playgroud)
这也产生相同的错误.
我在使用postgres 9.4实例获取此本机查询时遇到问题.
我的存储库有一个方法:
@Query(value = "SELECT t.* " +
"FROM my_table t " +
"WHERE t.field_1 = ?1 " +
"AND t.field_2 = 1 " +
"AND t.field_3 IN ?2 " +
"AND t.jsonb_field #>> '{key,subkey}' = ?3",
nativeQuery = true)
List<Entity> getEntities(String field1Value,
Collection<Integer> field3Values,
String jsonbFieldValue);
Run Code Online (Sandbox Code Playgroud)
但是日志显示了这个:
SELECT t.* FROM my_table t
WHERE t.field_1 = ?1
AND t.field_2 = 1
AND t.field_3 IN ?2
AND t.jsonb_field ? '{key,subkey}' = ?3
Run Code Online (Sandbox Code Playgroud)
我得到这个例外:
内部异常:org.postgresql.util.PSQLException:没有为参数2指定值.
我在方法调用之前直接记录了参数,并且它们都是提供的.
我不确定为什么在日志中#>>
显示?
.我需要逃脱 …
我的问题与以下问题相关:将postgreSQL JSON列映射到Hibernate值类型,尽管当我测试在postgres中将字符串传递给psql时答案有效,但从Java代码传递字符串时却无法解决问题。
我正在使用MyBatis通过Spring注入将sql映射到postgres数据库。
这是MyBatis的Java接口,映射到Postgres JSON列时遇到问题的方法是updateState()方法。
package receiver.spoke;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import receiver.bean.Spoke;
public interface SpokeDAOMyBatis extends SpokeDAO {
void updateState(@Param("id") long spokeId, @Param("state") String state);
String getState(@Param("id") long spokeId);
List<Spoke> getSpokes();
// The close() method must exist.
void close();
}
Run Code Online (Sandbox Code Playgroud)
以下是我的映射器类:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="receiver.spoke.SpokeDAOMyBatis">
<update id="updateState">
UPDATE
spokes
SET
state = #{state}
WHERE
id = #{id}
</update>
<select id="getState" resultType="java.lang.String"
parameterType="long" useCache="false">
SELECT
state
FROM
spokes
WHERE
id …
Run Code Online (Sandbox Code Playgroud) 我的应用程序使用slick(v2.0.0)来管理postgresql(9.1)数据库.
我的一个表包含网络设备,因此包含mac和ip地址.我使用了postgres类型macaddr
,inet
因为它们似乎是完成任务的完美工具.现在我想使用浮动的emebedding,但很难定义我的表.当我自动为我的表生成代码时,我注意到String
使用的是代替那些类型但不介意.
这适用于从数据库读取,但当我尝试更新或插入行时,它会导致
org.postgresql.util.PSQLException: ERROR:
column "mac" is of type macaddr but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Run Code Online (Sandbox Code Playgroud)
这似乎很合乎逻辑.
现在问题是如何告诉光滑:
macaddr
/inet
要么
?
更新:
克雷格说明我已经创建了周围使用包装函数隐式类型转换macaddr_in
和inet_in
\dC macaddr
List of casts
Source type | Target type | Function | Implicit?
-------------+-------------+----------------+-----------
text | macaddr | macaddr_intext | yes
\dC inet
List of casts
Source type | Target type …
Run Code Online (Sandbox Code Playgroud) postgresql ×9
jpa ×5
json ×4
jdbc ×3
spring ×3
eclipselink ×2
hibernate ×2
java ×2
slick ×2
casting ×1
json-patch ×1
jsonb ×1
mybatis ×1
scala ×1
sqldatatypes ×1
tomee ×1