sql >> Base de Datos >  >> RDS >> PostgreSQL

Error al mapear matrices de postgres en Spring JPA

Tal como lo ha señalado @ jeff-wang, los tipos de matrices de Postgres no son compatibles con JPA. Las implementaciones de mapeo específicas se pueden agregar manualmente, pero @vlad-mihalcea ya proporcionó una implementación de muestra. Lo obtienes de maven central:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>${hibernate-types.version}</version>
</dependency>

Puede encontrar más detalles aquí:https://vladmihalcea.com/how-to-map-java-and-sql-arrays-with-jpa-and-hibernate/

Después de resolver la dependencia, se debe agregar una implementación para el mapeo específico. Tomemos Postgres bigint[] como ejemplo. Se puede asignar, por ejemplo, a Long[] . En primer lugar, necesitamos agregar un descriptor para el tipo deseado:

import com.vladmihalcea.hibernate.type.array.internal.AbstractArrayTypeDescriptor;

public class LongArrayTypeDescriptor extends AbstractArrayTypeDescriptor<Long[]> {
    public static final LongArrayTypeDescriptor INSTANCE = new LongArrayTypeDescriptor();

    public LongArrayTypeDescriptor() {
        super(Long[].class);
    }

    protected String getSqlArrayType() {
        return "bigint";
    }
}

Después de eso, la clase de mapeo real:

import com.vladmihalcea.hibernate.type.array.internal.ArraySqlTypeDescriptor;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.usertype.DynamicParameterizedType;

import java.util.Properties;

public class LongArrayType extends AbstractSingleColumnStandardBasicType<Long[]> implements DynamicParameterizedType {

    public static final LongArrayType INSTANCE = new LongArrayType();

    public LongArrayType() {
        super(ArraySqlTypeDescriptor.INSTANCE, LongArrayTypeDescriptor.INSTANCE);
    }

    public String getName() {
        return "long-array";
    }

    @Override
    protected boolean registerUnderJavaType() {
        return true;
    }

    @Override
    public void setParameterValues(Properties parameters) {
        ((LongArrayTypeDescriptor) getJavaTypeDescriptor()).setParameterValues(parameters);
    }
}

Una vez hecho esto, todo lo que queda por hacer es tener en cuenta nuestras asignaciones en la configuración de Spring. Mantengo la configuración de mi modelo de datos por separado en forma basada en anotaciones:

import ibdb.model.mappers.LongArrayType;
import ibdb.model.mappers.ShortArrayType;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;

import javax.persistence.MappedSuperclass;

@TypeDefs({
        @TypeDef(
                name = "long-array",
                typeClass = LongArrayType.class
        ),
        @TypeDef(
                name = "short-array",
                typeClass = ShortArrayType.class
        )
})
@MappedSuperclass
public class DaoConfig {
}

Ahora todo está listo para usar. La columna de ejemplo anotada con una asignación recién agregada en la definición de DAO tiene el siguiente aspecto:

@Type(
        type = "long-array"
)
@Column(
        columnDefinition = "bigint[]"
)
private Long[] author;