Java 在hibernate中映射PostgreSQL LTREE列时出错

Java 在hibernate中映射PostgreSQL LTREE列时出错,java,postgresql,hibernate,entity,ltree,Java,Postgresql,Hibernate,Entity,Ltree,我试图在hibernate中映射postgresql ltree列,如下所示: public class LTreeType implements UserType { @Override public int[] sqlTypes() { return new int[] {Types.OTHER}; } @SuppressWarnings("rawtypes") @Override public Class returne

我试图在hibernate中映射postgresql ltree列,如下所示:

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);
    }

}
    @Column(name = "path", nullable = false, columnDefinition = "ltree")
    @Type(type = "LTreeType")
    private String path;
实体中:

private String path;

@Column(name="org_path", columnDefinition="ltree")
public String getPath() {
   return path;
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)]
表格结构:

private String path;

@Column(name="org_path", columnDefinition="ltree")
public String getPath() {
   return path;
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)]
获取以下错误:

private String path;

@Column(name="org_path", columnDefinition="ltree")
public String getPath() {
   return path;
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类,如下所示:

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);
    }

}
    @Column(name = "path", nullable = false, columnDefinition = "ltree")
    @Type(type = "LTreeType")
    private String path;
并对实体类进行注释,如下所示:

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);
    }

}
    @Column(name = "path", nullable = false, columnDefinition = "ltree")
    @Type(type = "LTreeType")
    private String path;

在我创建LQueryType之前,我一直都很适应,就像为LTreeType提供的@arnabbis类一样。 我的代码只知道字符串,但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>
val-dentids=treeRepo.findAllDescendantIds(“*.id.*{1,}”)
. . .
@质疑(
“从路径~CAST(:idQuery AS lquery)所在的树中选择节点_id;”
,nativeQuery=true)
fun findAllDescendantIds(@Param(“idQuery”)idQuery:String):数组

只需在@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;
}

该自定义类型是否在与相应实体保持一致时隐式获取?我的意思是,如果由“UserType”实现,hibernate是否定位并加载由“type”指定的类?或者,是否需要以某种方式将自定义类型引入Hibernate?对我来说,它似乎没有被接受,直到我使用“org.hibernate.boot.model.TypeContributor”来介绍我的自定义类型。@Raj或者你可以使用
@type(type=“com.my.package.LTreeType”)
@Raj或者另一种方式,在实体类上放置
@TypeDef(name=“ltree”,typeClass=LTreeType.class)
,然后
@type(type=“ltree”)