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?