Геодез данных весенней загрузки помещен в область, вызывающую дублирование строчных элементов PDX - PullRequest
1 голос
/ 31 января 2020

У меня есть объект домена MyRequest с именами переменных в верхнем регистре, который PDX-файл для области с именем myRequest. Вот объект домена:

package region;

import org.apache.geode.pdx.PdxReader;
import org.apache.geode.pdx.PdxSerializable;
import org.apache.geode.pdx.PdxSerializer;
import org.apache.geode.pdx.PdxWriter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.gemfire.mapping.annotation.Region;

import com.google.gson.Gson;

@Region("myRequest")
public class MyRequest implements PdxSerializer {
private static final Logger log = LogManager.getLogger(MyRequest.class);

private String Client;
private String Provider;
private String Msg;

public String getClient() { return Client; }
public void setClient(String client) { Client = client; }
public String getProvider() { return Provider; }
public void setProvider(String provider) { Provider = provider; }
public String getMsg() { return Msg; }
public void setMsg(String msg) { Msg = msg; }

public CmQuoteRequest()
{
    this.Msg = "";
}

public String ToJson(MyRequest qr)
{
    Gson gson = new Gson();
    return gson.toJson(qr);
}

public MyRequest ToMyRequest(String json)
{
    Gson gson = new Gson();
    return gson.fromJson(json, MyRequest.class);
}

public static PdxSerializable CreateDeserializable()
{
    return (PdxSerializable)new MyRequest();
}

public MyRequest(String Client, String Provider, String Msg) {
    log.traceEntry();

    this.Client = Client;
    this.Provider = Provider;
    this.Msg = Msg;

    log.traceExit();
}

@Override
public boolean toData(Object o, PdxWriter writer) {
    log.traceEntry();

    writer.writeString("Client", this.Client);
    writer.writeString("Provider", this.Provider);
    writer.writeString("Msg", this.Msg);

    log.traceExit();
    return true;
}

@Override
public Object fromData(Class<?> clazz, PdxReader reader) {
    log.traceEntry();

    this.Client = reader.readString("Client");
    this.Provider = reader.readString("Provider");
    this.Msg = reader.readString("Msg");

    log.traceExit();
        return null;
}
}

Используя геодезию с весенней загрузкой с webflux, я настроил доступ к региону для этих объектов домена следующим образом:

@Configuration
public class GeodeConfig {
private static final Logger log = LogManager.getLogger(GeodeConfig.class);

public static Region<String, MyRequest> myRequest;

@Bean("myRequestRegion")
public Region<String, MyRequest> myRequestRegion(GemFireCache cache) {
    log.traceEntry();

    Region<String, MyRequest> r = cache.getRegion("myRequest");
    myRequest = r;

    return r;
}

Затем я могу статически обратиться к эта область от конечных точек контроллера покоя, чтобы поместить туда данные объекта. Когда это происходит, вот так:

requests.stream().forEach(request -> {
    try {
        GeodeConfig.myRequest.put(id, request);
    } catch (Exception e) {
        new PutError("requestQueue", e);
    }
});

Я вижу в журналах, что переменные объекта MyRequest ... дублируются в нижнем регистре:

2020-01-31T17:32:43,019 DEBUG [http-nio-8082-exec-1] org.sprin.data.gemfi.mappi.MappingPdxSerializer 588 lambda$doToData$2: Serializing entity [region.MyRequest] property [Client] value [Client1] of type [java.lang.String] to PDX
2020-01-31T17:32:43,254 DEBUG [http-nio-8082-exec-1] org.sprin.data.gemfi.mappi.MappingPdxSerializer 588 lambda$doToData$2: Serializing entity [region.MyRequest] property [Provider] value [Provider1] of type [java.lang.String] to PDX
2020-01-31T17:32:43,270 DEBUG [http-nio-8082-exec-1] org.sprin.data.gemfi.mappi.MappingPdxSerializer 588 lambda$doToData$2: Serializing entity [region.MyRequest] property [Msg] value [R] of type [java.lang.String] to PDX
2020-01-31T17:32:43,644 DEBUG [http-nio-8082-exec-1] org.sprin.data.gemfi.mappi.MappingPdxSerializer 588 lambda$doToData$2: Serializing entity [region.MyRequest] property [provider] value [Provider1] of type [java.lang.String] to PDX
2020-01-31T17:32:43,673 DEBUG [http-nio-8082-exec-1] org.sprin.data.gemfi.mappi.MappingPdxSerializer 588 lambda$doToData$2: Serializing entity [region.MyRequest] property [client] value [Client1] of type [java.lang.String] to PDX

2020-01-31T17:32:43,904 INFO  [http-nio-8082-exec-1] org.apach.geode.pdx.inter.TypeRegistry 209 defineType: Caching PdxType[dsid=0, typenum=14943844
name=region.MyRequest
fields=[
Client:String:0:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=-1
Provider:String:1:1:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=1
Msg:String:2:2:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=2
provider:String:3:3:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=3
client:String:4:4:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=-1]

Когда я смотрю на регион в GF SH имеет дублирующиеся столбцы с именами в верхнем и нижнем регистре!

В то время как имена переменных объекта домена все в верхнем регистре ... теперь endemi c. Любые идеи, что происходит с экземплярами pdx, повторяется в нижнем регистре? Это своего рода беспорядок для нижестоящего.

1 Ответ

4 голосов
/ 04 февраля 2020

Прежде всего, я не уверен, почему класс вашего домена реализует PdxSerializer. PdxSerializer должен быть отдельным классом, который вы регистрируете в кеше, хотя в этом случае он вам даже не нужен, потому что Spring автоматически использует MappingPdxSerializer. Хотя это неверно, это не является причиной вашей проблемы, поскольку такое же поведение происходит, даже если вы удалили все вещи PdxSerializer из вашего класса.

Проблема в том, что вы не придерживаетесь Спецификация JavaBeans . По соглашению, в Java поля должны начинаться с символа нижнего регистра. Когда объект сериализуется, платформа просматривает методы получения и установки, чтобы определить, что следует сохранить. Следуя соглашению, методы getClient() и setClient() подразумевают существование свойства с именем "client". Поскольку Java чувствителен к регистру, «клиент» и «клиент» НЕ одинаковы.

Лучшее решение проблемы с дублирующимся полем - это изменить имена полей в соответствии с соглашением об именах Java .

Если по какой-то причине вы не можете изменить имена полей, вы можете реализовать свой собственный PdxSerializer (что вы уже сделали внутри своего класса MyRequest). Ниже приведен пример реализации PdxSerializer, которая должна делать то, что вы хотите:

public class CustomSerializer implements PdxSerializer {
    @Override
    public boolean toData(Object o, PdxWriter pdxWriter) {
        if(o instanceof MyRequest) {
            MyRequest request = (MyRequest)o;
            pdxWriter.writeString("Client", request.getClient());
            pdxWriter.writeString("Msg", request.getMsg());
            pdxWriter.writeString("Provider", request.getProvider());
            return true;
        }
        return false;
    }

    @Override
    public Object fromData(Class<?> aClass, PdxReader pdxReader) {
        MyRequest request;
        try {
            request = (MyRequest) aClass.getConstructor().newInstance();
            request.setClient(pdxReader.readString("Client"));
            request.setMsg(pdxReader.readString("Msg"));
            request.setProvider(pdxReader.readString("Provider"));
            return request;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

Чтобы зарегистрировать этот сериализатор, вам нужно определить bean-компонент типа CustomSerializer в вашей конфигурации, как показано ниже:

@Bean("customSerializer")
public CustomSerializer customSerializer() {
    return new CustomSerializer();
}

и затем аннотируйте свой класс конфигурации с помощью @EnablePdx(serializerBeanName = "customSerializer"). Это должно правильно сопоставить ваши поля без дублирования.

...