在休眠中映射 PostgreSQL LTREE 列时出错
Getting error when mapping PostgreSQL LTREE column in hibernate
我正尝试在休眠中映射 postgresql ltree 列,如下所示:
在实体中:
private String path;
@Column(name="org_path", columnDefinition="ltree")
public String getPath() {
return path;
Table结构:
CREATE TABLE relationship (
relationship_id int4 NOT NULL,
parent_organization_id uuid NOT NULL,
child_organization_id uuid NOT NULL,
org_path ltree NOT NULL,
CONSTRAINT relationship_pk PRIMARY KEY (relationship_id),
CONSTRAINT organization_fk3 FOREIGN KEY (parent_organization_id) REFERENCES organization(organization_id) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT organization_fk4 FOREIGN KEY (child_organization_id) REFERENCES organization(organization_id) ON DELETE RESTRICT ON UPDATE RESTRICT
)
出现以下错误:
wrong column type encountered in column [org_path] in table [relationship]; found [“schemaName"."ltree" (Types#OTHER)], but expecting [ltree (Types#VARCHAR)]
谁能帮忙解决这个问题?
在 Java 中实现自定义 LTreeType class,如下所示:
public class LTreeType implements UserType {
@Override
public int[] sqlTypes() {
return new int[] {Types.OTHER};
}
@SuppressWarnings("rawtypes")
@Override
public Class returnedClass() {
return String.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return x.equals(y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
return rs.getString(names[0]);
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
st.setObject(index, value, Types.OTHER);
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return new String((String)value);
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable)value;
}
@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
// TODO Auto-generated method stub
return deepCopy(original);
}
}
并注释实体 class 如下:
@Column(name = "path", nullable = false, columnDefinition = "ltree")
@Type(type = "LTreeType")
private String path;
直到我还创建了一个 LQueryType,就像为 LTreeType 提供的 class @arnabbiswas 一样,我一直感到不适。
我的代码只知道字符串,但 Postgres 不知道如何将 ltree 与字符串一起使用。类型和操作是:
ltree ~ lquery
ltree @> ltree
所以我的 Kotlin JPA 是这样的:
val descendantIds = treeRepo.findAllDescendantIds("*.$id.*{1,}")
. . .
@Query(
"SELECT node_id FROM tree WHERE path ~ CAST(:idQuery AS lquery);"
, nativeQuery = true)
fun findAllDescendantIds(@Param("idQuery") idQuery: String): Array<Long>
只需在@anarbbswas 代码上添加此修改即可正常工作
@Override
public Object nullSafeGet(ResultSet rs, String[] names,SharedSessionContractImplementor session, Object owner)
throws HibernateException, SQLException {
return rs.getString(names[0]);
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
st.setObject(index, value, Types.OTHER);
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if (value == null)
return null;
if (! (value instanceof String))
throw new IllegalStateException("Expected String, but got: " + value.getClass());
return value;
}
我正尝试在休眠中映射 postgresql ltree 列,如下所示:
在实体中:
private String path;
@Column(name="org_path", columnDefinition="ltree")
public String getPath() {
return path;
Table结构:
CREATE TABLE relationship (
relationship_id int4 NOT NULL,
parent_organization_id uuid NOT NULL,
child_organization_id uuid NOT NULL,
org_path ltree NOT NULL,
CONSTRAINT relationship_pk PRIMARY KEY (relationship_id),
CONSTRAINT organization_fk3 FOREIGN KEY (parent_organization_id) REFERENCES organization(organization_id) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT organization_fk4 FOREIGN KEY (child_organization_id) REFERENCES organization(organization_id) ON DELETE RESTRICT ON UPDATE RESTRICT
)
出现以下错误:
wrong column type encountered in column [org_path] in table [relationship]; found [“schemaName"."ltree" (Types#OTHER)], but expecting [ltree (Types#VARCHAR)]
谁能帮忙解决这个问题?
在 Java 中实现自定义 LTreeType class,如下所示:
public class LTreeType implements UserType {
@Override
public int[] sqlTypes() {
return new int[] {Types.OTHER};
}
@SuppressWarnings("rawtypes")
@Override
public Class returnedClass() {
return String.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return x.equals(y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
return rs.getString(names[0]);
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
st.setObject(index, value, Types.OTHER);
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return new String((String)value);
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable)value;
}
@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
// TODO Auto-generated method stub
return deepCopy(original);
}
}
并注释实体 class 如下:
@Column(name = "path", nullable = false, columnDefinition = "ltree")
@Type(type = "LTreeType")
private String path;
直到我还创建了一个 LQueryType,就像为 LTreeType 提供的 class @arnabbiswas 一样,我一直感到不适。 我的代码只知道字符串,但 Postgres 不知道如何将 ltree 与字符串一起使用。类型和操作是:
ltree ~ lquery
ltree @> ltree
所以我的 Kotlin JPA 是这样的:
val descendantIds = treeRepo.findAllDescendantIds("*.$id.*{1,}")
. . .
@Query(
"SELECT node_id FROM tree WHERE path ~ CAST(:idQuery AS lquery);"
, nativeQuery = true)
fun findAllDescendantIds(@Param("idQuery") idQuery: String): Array<Long>
只需在@anarbbswas 代码上添加此修改即可正常工作
@Override
public Object nullSafeGet(ResultSet rs, String[] names,SharedSessionContractImplementor session, Object owner)
throws HibernateException, SQLException {
return rs.getString(names[0]);
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
st.setObject(index, value, Types.OTHER);
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if (value == null)
return null;
if (! (value instanceof String))
throw new IllegalStateException("Expected String, but got: " + value.getClass());
return value;
}