ClassCastException while accessing table with array of Enum

Hi everybody,

I have the exception while accessing a table with a column mapped as array of Enum.

Code below
SQL

CREATE TYPE ${dbSchema}.st_charttype AS ENUM (‘ST_BARCHARTHORIZONTAL’,
‘ST_BARCHARTVERTICAL’,
‘ST_BARCHARTSTACKED’,
‘ST_BARCHARTVS’,
‘ST_LINECHARTBASIC’,
‘ST_LINECHARTSTEPPED’,
‘ST_AREACHARTBOUNDARIES’,
‘ST_AREACHARTDATASET’,
‘ST_AREACHARTSTACKED’,
‘ST_AREACHARTRADAR’,
‘ST_PIECHART’);

CREATE TABLE {dbSchema}.st_availablechart ( ID SERIAL PRIMARY KEY, propertyID INTEGER NOT NULL REFERENCES {dbCoreSchema}.lt_familyproperty(ID) ON UPDATE CASCADE ON DELETE CASCADE,
charttype {dbSchema}.st_charttype[] NOT NULL DEFAULT ARRAY['ST_LINECHARTBASIC']::{dbSchema}.st_charttype[],
insert_date TIMESTAMP NOT NULL DEFAULT NOW());

Table mapping

@LTPlugin
@TypeDefs({ @TypeDef(
name = “enumChartType”,
typeClass = EnumArrayType.class,
defaultForType = EChartType[].class,
parameters = {
@Parameter(name = EnumArrayTypeDescriptor.SQL_ARRAY_TYPE,
value = STDBConfig.STSchema + “.st_charttype”)
})
})

@Entity(name = “ChartType”)
@Table(name = “st_availablechart”, schema = STDBConfig.STSchema)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@NaturalIdCache
@LTEhcache(template = CacheTemplate.LONG_TIME_SMALL)
public class ChartType implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", insertable = false, updatable = false, nullable = false)
protected Integer id;

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "propertyID", nullable = false, insertable = false, updatable = false)
private FamilyProperty familyProperty;

@NaturalId
@Column(name = "propertyID", insertable = true, nullable = false, updatable = false)
private Integer propertyId;

@Column(name = "charttype", columnDefinition = STDBConfig.STSchema
		+ ".st_charttype[]", insertable = true, nullable = false, updatable = true)
private EChartType[] eChartType = { EChartType.ST_LINECHARTBASIC };

public Integer getId() {
	return id;
}

public FamilyProperty getFamilyProperty() {
	return familyProperty;
}

public Integer getPropertyId() {
	return propertyId;
}

public void setId(Integer id) {
	this.id = id;
}

public void setPropertyId(Integer propertyId) {
	this.propertyId = propertyId;
}

public EChartType[] geteChartType() {
	return eChartType;
}

public void seteChartType(EChartType[] eChartType) {
	this.eChartType = eChartType;
}

@Override
public boolean equals(Object o) {
	if (this == o)
		return true;
	if (o == null || !getClass().equals(o.getClass()))
		return false;
	ChartType chartType = (ChartType) o;
	return Objects.equals(propertyId, chartType.propertyId);
}

@Override
public int hashCode() {
	return propertyId.hashCode();
}

}

Type mapping

package lt.database.mapping.type;

import java.util.Properties;

@SuppressWarnings(“rawtypes”)
public class EnumArrayTypeDescriptor extends ArrayTypeDescriptor {

private static final long serialVersionUID = 1L;
public static final EnumArrayTypeDescriptor INSTANCE = 
		new EnumArrayTypeDescriptor();

public static final String SQL_ARRAY_TYPE = "sql_array_type";

private String sqlArrayType;

public EnumArrayTypeDescriptor() {
	super(Enum[].class);
}

@Override
protected String getSqlType() {
	return sqlArrayType;
}

@Override
public void setParameterValues(Properties parameters) {
	sqlArrayType = parameters.getProperty(SQL_ARRAY_TYPE);
	super.setParameterValues(parameters);
}

}
public abstract class ArrayTypeDescriptor extends LTTypeDescriptor<T[]> {

private static final long serialVersionUID = 5543671733121514528L;

private Class<T[]> type;

public ArrayTypeDescriptor(Class<T[]> objectClass) {
	super(objectClass, new LTMutableMutabilityPlan<T[]>() {

		private static final long serialVersionUID = 4910118325309432138L;

		@Override
		protected T[] deepCopyObject(Object object) {
			return Arrays.copyOf(objectClass.cast(object), objectClass.cast(object).length);
		}
	});
	type = objectClass;
}

@Override
protected boolean isEqual(Object one, Object another) {
	if(one == another) return true;
	if (one == null || another == null) return false;
	if(!one.getClass().equals(another.getClass())) return false;
	return Arrays.equals(type.cast(one), type.cast(another));
}

@Override
protected String deepToString(Object object) {
	return null;
}

@Override
protected T[] fromString(String string, Class<?> type) {
	return null;
}

@Override
protected <X> T[] unwrap(X value, Class<?> type) {
	if(value != null && value instanceof PgArray) {
		PgArray array = (PgArray) value;
		try {
			return this.type.cast(array.getArray());
	} catch (SQLException e) {
		throw new IllegalArgumentException(e);
	}
}
	return null;
}

@Override
protected Object wrap(Object object) {
	return object;
}

}

public abstract class LTTypeDescriptor
extends AbstractTypeDescriptor
implements DynamicParameterizedType {

private static final long serialVersionUID = -7228311524381920040L;
private Class<?> objectClass;

@Override
public void setParameterValues(Properties parameters) {
	objectClass = ((ParameterType) parameters.get(PARAMETER_TYPE))
			.getReturnedClass();
}

public LTTypeDescriptor(Class<T> objectClass, MutableMutabilityPlan<T> mutabilityPlan) {
	super(objectClass, (MutabilityPlan<T>) mutabilityPlan);
	this.objectClass = objectClass;
}

@Override
public boolean areEqual(Object one, Object another) {
	if (one == another) return true;
	if (one == null || another == null) return false;
	return isEqual(one, another);
}

@Override
public String toString(Object value) {
	return deepToString(value);
}

@Override
public T fromString(String string) {
	return fromString(string, objectClass);
}

@Override
@SuppressWarnings("unchecked")
public <X> X unwrap(T value, Class<X> type, WrapperOptions options) {
	if (type != null)
		return type.cast(wrap(value));
	return (X) wrap(value);
}

@Override
public <X> T wrap(X value, WrapperOptions options) {
	return unwrap(value, objectClass);
}

protected abstract boolean isEqual(Object one, Object another);

protected abstract String deepToString(Object object);

protected abstract T fromString(String string, Class<?> type);

protected abstract Object wrap(Object object);

protected abstract <X> T unwrap(X value, Class<?> type);

protected abstract String getSqlType();

}

This is the code that raises exception

CriteriaQuery query = session.getCriteriaBuilder().createQuery(ChartType.class); Root root = query.from(ChartType.class); query.select(root); System.out.println("Before"); List chartTypes = session.createQuery(query).setCacheable(true).getResultList(); System.out.println("After");

ERROR statistic.controller.STController - Failed to get init data! exception is: java.lang.ClassCastException: Cannot cast [Ljava.lang.Object; to [Ljava.lang.Enum;

What I’m doing wrong?

I also add the enum
public enum EChartType {
ST_BARCHARTHORIZONTAL,
ST_BARCHARTVERTICAL,
ST_BARCHARTSTACKED,
ST_BARCHARTVS,
ST_LINECHARTBASIC,
ST_LINECHARTSTEPPED,
ST_AREACHARTBOUNDARIES,
ST_AREACHARTDATASET,
ST_AREACHARTSTACKED,
ST_AREACHARTRADAR,
ST_PIECHART;
}