Search code examples
javapostgresqlhibernateentityltree

Getting error when mapping PostgreSQL LTREE column in hibernate


I am trying to map postgresql ltree column in hibernate as follows:

In entity :

private String path;

@Column(name="org_path", columnDefinition="ltree")
public String getPath() {
   return path;

Table structure:

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
)

Getting the following error:

wrong column type encountered in column [org_path] in table [relationship]; found [“schemaName"."ltree" (Types#OTHER)], but expecting [ltree (Types#VARCHAR)]

Can anyone help how to resolve this issue?


Solution

  • Implement a custom LTreeType class in Java as follows:

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

    And annotate the Entity class as follows:

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