Вечер добрый.
demo1.zip (89.5 КБ)
(Для удачной сборки адреса репозиториев нужно поправить, у нас локальные используются.)
Имеетя абстрактная родительская сущность AbstractClient
:
@JmixEntity
@Table(name = "DEMO1_CLIENT")
@Entity(name = "demo1_AbstractClient")
public abstract class AbstractClient<T> {
@JmixGeneratedValue
@Id
@Column(name = "ID", nullable = false)
private UUID id;
@NotNull
@Column(name = "TYPE_", nullable = false)
protected String type;
/* Getters and Setters */
@NotNull
public abstract T getType();
public abstract void setType(@NotNull T type);
}
У неё атрибут type
строковый, но getter и setter абстрактные, чтобы в наследнике могли возвращать EnumClass
по значению ключа, а может и что-то другое, или даже туже самую строку.
Имеется наследник Customer
:
@JmixEntity
@Entity(name = "demo1_Customer")
public class Customer extends AbstractClient<CustomerType> {
@Override
public CustomerType getType() {
return type == null ? null : CustomerType.fromId(type);
}
@Override
public void setType(CustomerType type) {
this.type = type == null ? null : type.getId();
}
}
И Enum CustomerType
:
public enum CustomerType implements EnumClass<String> {
ORDINAL("ORDINAL"),
VIP("VIP");
private final String id;
CustomerType(String id) {
this.id = id;
}
public String getId() {
return id;
}
@Nullable
public static CustomerType fromId(String id) {
for (CustomerType at : CustomerType.values()) {
if (at.getId().equals(id)) {
return at;
}
}
return null;
}
}
В результате, при попытке открыть сущность Customer
в Entity Inspector получаю исключение:
ClassCastException: class com.company.demo1.common.CustomerType cannot be cast to class java.lang.String (com.company.demo1.common.CustomerType is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')
Подебажив немного я обнаружил что MetaProperty demo1_Customer.type
не является собственной property у MetaClass demo1_Customer
, а приезжает из MetaClass demo1_AbstractClient
и имеет тип String.
И далее, любая механика, которая берёт у MetaProperty её Datatype и применяет format() выбрасывает искючение.
Конкретно у EntityInspectorBrowse
в какой-то момент вызывается MetadataTools.format()
и далее StringDatatype.format()
, где выполняется приведение типа CustomerType
в String
.
Вопрос: как-то можно легально указать необходимый в наследнике тип данных атрибута?
Я некоторым образом в рантайме подменяю MetaProperty
но это выглядит как ненадёжный костыль.
В демо проекте changelog добавляет запись в БД для Customer
и чтобы увидеть ошибку достаточно открыть в инспекторе список.