Java Microstream - Syntheti c классы - PersistenceExceptionTypeNotPersistable - PullRequest
0 голосов
/ 05 августа 2020

При использовании Microstream возникает исключение, указанное ниже. Вызывается классом со ссылкой на внутренний класс stati c. Как решить эту проблему?

В исключении указано следующее, но в документации не объясняется, как реализовать PersistenceTypeResolver

Подробности: Syntheti c классы ($ 1 et c.) Не являются надежно постоянными, поскольку простое переупорядочение элементов исходного кода изменило бы идентичность имени класса. Для системы типов, которая должна полагаться на разрешение типов по их идентифицирующему имени, это молча вызовет потенциально фатальную ошибку. Если обработка классов syntheti c (например, анонимных внутренних классов) абсолютно необходима, можно использовать настраиваемый one.microstream.persistence.types.PersistenceTypeResolver для удаления исключения и принятия на себя полной ответственности за правильную обработку имен классов syntheti c. на one.microstream.persistence.types.Persistence.derivePersistentTypeName (Persistence. java: 1083)

    public static final AbstractAccompanyingPassenger DUMMY = new AbstractAccompanyingPassenger(MetaDataAccompanyingType.DUMMY) {
        @Override
        public AbstractAccompanyingPassenger clone() {
            return DUMMY;
        }};
Caused by: one.microstream.persistence.exceptions.PersistenceExceptionTypeNotPersistable: Type not persistable: "class net.atpco.metadata.summary.accompanied.MetaDataAccompanying$1". Details: Synthetic classes ($1 etc.) are not reliably persistence since a simple reordering of source code elements would change the name identity of a class. For a type system that has to rely upon resolving types by their identifying name, this would silently cause a potentially fatal error. If handling synthetic classes (e.g. anonymous inner classes) is absolutely necessary, a custom one.microstream.persistence.types.PersistenceTypeResolver can be used to remove the exception and assume  complete responsibility for correctly handling synthetic class names.
    at one.microstream.persistence.types.Persistence.derivePersistentTypeName(Persistence.java:1083)
    at one.microstream.persistence.types.PersistenceTypeResolver.deriveTypeName(PersistenceTypeResolver.java:17)
    at one.microstream.persistence.types.PersistenceTypeHandlerCreator$Abstract.deriveTypeName(PersistenceTypeHandlerCreator.java:73)
    at one.microstream.persistence.binary.types.BinaryTypeHandlerCreator$Default.internalCreateTypeHandlerGeneric(BinaryTypeHandlerCreator.java:238)
    at one.microstream.persistence.types.PersistenceTypeHandlerCreator$Abstract.createTypeHandlerGeneric(PersistenceTypeHandlerCreator.java:168)
    at one.microstream.persistence.types.PersistenceTypeHandlerEnsurer$Default.ensureTypeHandler(PersistenceTypeHandlerEnsurer.java:199)
    at one.microstream.persistence.internal.PersistenceTypeHandlerProviderCreating.ensureTypeHandler(PersistenceTypeHandlerProviderCreating.java:170)
    at one.microstream.persistence.internal.PersistenceTypeHandlerProviderCreating.provideTypeHandler(PersistenceTypeHandlerProviderCreating.java:78)
    at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.internalEnsureTypeHandler(PersistenceTypeHandlerManager.java:587)
    at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.ensureTypeHandler(PersistenceTypeHandlerManager.java:357)
    at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.ensureTypeHandler(PersistenceTypeHandlerManager.java:333)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.registerGuaranteed(BinaryStorer.java:557)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.registerLazyOptional(BinaryStorer.java:572)
    at one.microstream.persistence.types.PersistenceObjectManager$Default.ensureObjectId(PersistenceObjectManager.java:182)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.register(BinaryStorer.java:591)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.apply(BinaryStorer.java:298)
    at one.microstream.persistence.binary.types.BinaryValueFunctions$9.storeValueFromMemory(BinaryValueFunctions.java:147)
    at one.microstream.persistence.binary.types.Binary.storeFixedSize(Binary.java:1149)
    at one.microstream.persistence.binary.internal.AbstractBinaryHandlerReflective.store(AbstractBinaryHandlerReflective.java:497)
    at one.microstream.persistence.binary.internal.AbstractBinaryHandlerReflective.store(AbstractBinaryHandlerReflective.java:1)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.storeItem(BinaryStorer.java:414)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.storeGraph(BinaryStorer.java:403)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.store(BinaryStorer.java:421)
    at one.microstream.persistence.types.PersistenceManager$Default.store(PersistenceManager.java:274)
    at one.microstream.storage.types.StorageConnection.store(StorageConnection.java:306)
    at one.microstream.cache.CacheStore$Default.write(CacheStore.java:112)

Ответы [ 2 ]

0 голосов
/ 07 августа 2020

Я нашел решение этой проблемы без необходимости изменять Java структуру графа объекта и иметь ссылки на Syntheti c Classes / stati c.

  1. Реализовать CustomBinaryHandler для объекта, который имеет Syntheti c Classes / stati c reference
  2. Переопределить метод store
  3. Переопределить create method
  4. Переопределить initializeState method

Store

Если ссылка на Syntheti c Classes / stati c ссылки создают новый экземпляр объекта и устанавливают ссылку на «маркер». В моем случае до нуля. Не обновляйте текущий объект, переданный в метод store , обязательно создайте клон и измените применимую ссылку. Затем вызовите super.store ()

create

Создайте пустой экземпляр объекта

initializeState

  1. Получить значения для объекта
  2. Если у рассматриваемого значения есть 'маркер', установите его на Syntheti c Classes / stati c reference
  3. Создайте объект-клон и заполните его значения
  4. XReflect.copyFields от клона до реального экземпляра
public class ExampleTypeHandler extends CustomBinaryHandler<Example> {

    private static Class<Example> handledType() {
        return Example.class; // to get ".class" to work
    }
    
    //the fields to be persisted
    BinaryField<Example> accompanying = Field(Object.class, Example::getAccompanying);
    BinaryField<Example> resulting = Field(Object.class, Example::getResulting);
    
    public ExampleTypeHandler()
    {
        super(handledType());
    }
    
    @Override
    public void store(Binary data, Example dtl, long objectId, PersistenceStoreHandler<Binary> handler) {
        if (dtl.getAccompanying() == MetaDataAccompanying.DUMMY) {
            dtl = Example.of(dtl.getResulting(), null);
        }
        super.store(data, dtl, objectId, handler);
    }
    
    @Override
    public Example create(final Binary data, final PersistenceLoadHandler handler) {
        return Example.of(null, null);
    }

    @Override
    public void initializeState(final Binary data, final Example instance, final PersistenceLoadHandler handler) {
        //get the referenced Objects
        Object accompanying = this.accompanying.readReference(data, handler);
        String r = (String)this.resulting.readReference(data, handler);
            
        if (accompanying == null) {
            accompanying = MetaDataAccompanying.DUMMY;
        }

        MetaDataAccompanying a = (MetaDataAccompanying) accompanying;
        Example dtl = Example.of(r, a);
        
        XReflect.copyFields(dtl, instance);
    }       
    
}
0 голосов
/ 06 августа 2020

Как указано в исключении, сохраняющиеся классы Syntheti c не поддерживаются. В вашем случае рефакторинг ваших классов, чтобы избавиться от этих синтетических c классов, является единственным надежным вариантом.

...