将Javers与协议缓冲区对象一起使用

时间:2019-01-30 14:30:36

标签: java protocol-buffers javers

使用Javers时遇到一个问题。 我有两个带有协议缓冲区的生成类的对象。

如果我要比较这两个对象,我有:

Exception in thread "main" JaversException MANAGED_CLASS_MAPPING_ERROR: given javaClass 'class com.google.protobuf.UnmodifiableLazyStringList' is mapped to ListType, expected ManagedType
    at org.javers.core.metamodel.type.TypeMapper.getJaversManagedType(TypeMapper.java:201)
    at org.javers.core.metamodel.type.TypeMapper.getJaversManagedType(TypeMapper.java:184)
    at org.javers.core.metamodel.object.GlobalIdFactory.createId(GlobalIdFactory.java:50)
    at org.javers.core.graph.LiveCdoFactory.create(LiveCdoFactory.java:29)
    at org.javers.core.graph.LiveCdoFactory.create(LiveCdoFactory.java:15)
    at org.javers.core.graph.EdgeBuilder.buildSingleEdge(EdgeBuilder.java:30)
    at org.javers.core.graph.ObjectGraphBuilder.buildSingleEdges(ObjectGraphBuilder.java:80)
    at org.javers.core.graph.ObjectGraphBuilder.buildEdges(ObjectGraphBuilder.java:70)
    at org.javers.core.graph.ObjectGraphBuilder.buildGraphFromCdo(ObjectGraphBuilder.java:58)
    at org.javers.core.graph.ObjectGraphBuilder.buildGraph(ObjectGraphBuilder.java:47)
    at org.javers.core.graph.LiveGraphFactory.createLiveGraph(LiveGraphFactory.java:39)
    at org.javers.core.diff.DiffFactory.buildGraph(DiffFactory.java:99)
    at org.javers.core.diff.DiffFactory.compare(DiffFactory.java:54)
    at org.javers.core.JaversCore.compare(JaversCore.java:173)
    at test.performance.javers.ComparaisonJaVers.main(ComparaisonJaVers.java:38)

当我在protobuf中使用重复的字符串时,问题来自UnmodifiableLazyStringList。

repeated string info = 7;

原始文件

    package proto;

// used to indicate explicitly where to generate in java (optional)
option java_package = "data.generated";

// proto_name (optional)
//option java_outer_classname = "Foret";

//by default, we will use LLite runtime for protocol buffer library
option optimize_for = LITE_RUNTIME;

//type
enum Type {
    TYPE_ARBRE = 0;
    TYPE_ANIMAL = 1;
    TYPE_OISEAU = 2;
    TYPE_SOUS_SOL = 3;
}

//importance
enum Priorite {
    PRIORITE_ELEVE = 0;
    PRIORITE_NORMAL = 1;
    PRIORITE_BASSE = 2;
}

//type d'arbre
enum TypeArbre {
    TYPEARBRE_RESINEU = 0;
    TYPEARBRE_FEUILLU = 1;
    TYPEARBRE_FRUITIER = 2;
}

//race d'arbre
enum RaceArbre {
    RACEARBRE_EPICEA = 0;
    RACEARBRE_HETRE_ROUX = 1;
    RACEARBRE_CHENE = 2;
    RACEARBRE_BOULEAU = 3;
    RACEARBRE_POIRIER = 4;
    RACEARBRE_MEURISIER = 5;
    RACEARBRE_ORANGER_MEXIQUE = 6;
    RACEARBRE_POMMIER = 7;
}

//type d'animal
enum TypeAnimal {
    TYPEARBRE_CHIEN = 0;
    TYPEARBRE_CHAT = 1;
    TYPEARBRE_OURS = 2;
    TYPEARBRE_LAPIN = 3;
    TYPEARBRE_GIRAFE = 4;
}

//race d'aniaml
enum RaceAnimal {
    RACEANIMAl_GOLDEN = 0;
    RACEANIMAl_LUMPEA = 1;
    RACEANIMAl_GIROFON = 2;
    RACEANIMAl_LEVIRER = 3;
    RACEANIMAl_ULSKY = 4;
    RACEANIMAl_RETRIVERS = 5;
    RACEANIMAl_LABRADOR = 6;
    RACEANIMAl_OURSIN = 7;
}

enum TypeFeuille {
    TYPEFEUILLE_PAPIER = 0;
    TYPEFEUILLE_CANSON = 1;
    TYPEFEUILLE_CARTON = 2;
    TYPEFEUILLE_BUVARD = 3;
    TYPEFEUILLE_COULEUR = 4;
    TYPEFEUILLE_CALC = 5;
    TYPEFEUILLE_PLASTIFIEE = 6;
    TYPEFEUILLE_AUTRE = 7;
}

message Foret {
    optional sint32 id = 1;
    optional string nom = 2;
    optional Priorite priority = 3;
    repeated Arbre arbre = 4;
    repeated Animal animal = 5;
    repeated sint32 taille = 6;
    repeated string info = 7;
}

message Arbre {
    optional sint32 id = 1;
    optional Type type = 2;
    optional TypeArbre typeArbre = 3;
    optional RaceArbre race = 4;
    optional sint32 annee = 5;
    optional Priorite priorite = 6;
    optional string nom = 7;
    repeated Feuille feuille = 8;
}

message Feuille {
    optional sint32 id = 1;
    optional TypeFeuille typeFeuille = 2;
    optional string nom = 3;
}

message Animal {
    optional sint32 id = 1;
    optional Type type = 2;
    optional TypeAnimal typeAnimal = 3;
    optional RaceAnimal race = 4;
    optional sint32 annee = 5;
    optional Priorite priorite = 6;
    repeated string nom = 7;
}

用于将对象生成为两个文件的类

public class ForetDAO {

    private static final String FILE_FORET_1 = "foret1.txt";
    private static final String FILE_FORET_2 = "foret2.txt";
    private static final ArrayList<String> excludedField = new ArrayList<>();
    private static Logger logger = Logger.getLogger(ForetDAO.class);

    public ForetDAO() {
        ForetDAO.excludedField.add("unknownFields");
        ForetDAO.excludedField.add("bitField0_");
        ForetDAO.excludedField.add("hash");
        ForetDAO.excludedField.add("memoizedIsInitialized");
        ForetDAO.excludedField.add("memoizedSerializedSize");
        ForetDAO.excludedField.add("bytes");
    }

    private static ForetOuterClass.Foret.Builder newForet() {

        ForetOuterClass.Foret.Builder foretBuilder = ForetOuterClass.Foret.newBuilder();
//        foretBuilder.addInfo("info 1");
        foretBuilder.setId(111111111);
        foretBuilder.setNom("Timberland");
        foretBuilder.setPriority(ForetOuterClass.Priorite.valueOf(1));
        foretBuilder.addTaille(5300);
        foretBuilder.addTaille(854);
        foretBuilder.addTaille(789);

        for (int i = 0; i < 25; i++) {
            foretBuilder.addArbre(arbre(i));
            foretBuilder.addAnimal(animal(i));
        }

        return foretBuilder;
    }

    private static void generateBinaryFile(ForetOuterClass.Foret.Builder foretBuilder, String fileName) {

        ForetOuterClass.Foret foret = foretBuilder.build();

        try (FileOutputStream fos = new FileOutputStream(fileName)) {
            fos.write(foret.toByteArray());
        } catch (IOException e) {
            logger.error(e);
        }

    }

    public static ForetOuterClass.Foret readFile(String fileName) {
        try {
            return ForetOuterClass.Foret.parseFrom(new FileInputStream(fileName));
        } catch (IOException e) {
            logger.error(e);
        }
        return null;
    }

    private static ForetOuterClass.Arbre arbre(int i) {

        ForetOuterClass.Arbre.Builder arbreBuilder = ForetOuterClass.Arbre.newBuilder();
        arbreBuilder.setId(i);
        arbreBuilder.setType(ForetOuterClass.Type.valueOf(i % 4));
        arbreBuilder.setTypeArbre(ForetOuterClass.TypeArbre.valueOf(i % 3));
        arbreBuilder.setRace(ForetOuterClass.RaceArbre.valueOf(i % 8));
        arbreBuilder.setAnnee(2019 - i);
        arbreBuilder.setPriorite(ForetOuterClass.Priorite.valueOf(i % 3));
        arbreBuilder.setNom("arbre " + i);
        for (int j = 0; j < 5; j++) {
            arbreBuilder.addFeuille(feuille(i));
        }

        return arbreBuilder.build();
    }

    private static ForetOuterClass.Animal animal(int i) {
        ForetOuterClass.Animal.Builder animalBuilder = ForetOuterClass.Animal.newBuilder();
        animalBuilder.setId(i);
        animalBuilder.setType(ForetOuterClass.Type.valueOf(i % 4));
        animalBuilder.setTypeAnimal(ForetOuterClass.TypeAnimal.valueOf(i % 5));
        animalBuilder.setRace(ForetOuterClass.RaceAnimal.valueOf(i % 8));
        animalBuilder.setAnnee(i + 1950);
        animalBuilder.setPriorite(ForetOuterClass.Priorite.valueOf(i % 3));
  /*      animalBuilder.addNom("animala " + i).build();
        animalBuilder.addNom("animalb " + i).build();
        animalBuilder.addNom("animalc " + i).build();
        animalBuilder.addNom("animald " + i).build();
        animalBuilder.addNom("animale " + i).build();*/

        return animalBuilder.build();
    }

    private static ForetOuterClass.Feuille feuille(int i) {
        ForetOuterClass.Feuille.Builder feuilleBuilder = ForetOuterClass.Feuille.newBuilder();

        feuilleBuilder.setId(i);
        feuilleBuilder.setTypeFeuille(ForetOuterClass.TypeFeuille.valueOf(i % 8));

        return feuilleBuilder.build();
    }

    public static void main(String[] args) {
        ForetOuterClass.Foret.Builder foretBuilder1;
        ForetOuterClass.Foret.Builder foretBuilder2;

        foretBuilder1 = ForetDAO.newForet();
        foretBuilder2 = ForetDAO.newForet();

        for (int i = 26; i < 28; i++) {
            foretBuilder2.addArbre(foretBuilder1.getArbre(0));
            foretBuilder2.addAnimal(animal(i));
        }

        foretBuilder2.setNom("Timberlend");
        foretBuilder2.setId(987654321);
        foretBuilder2.setTaille(1, 987654321);
        foretBuilder2.setTaille(2, 854);
        foretBuilder2.setTaille(1, 789);
        foretBuilder2.addTaille(123456879);
        foretBuilder2.setTaille(2, 0);

//        foretBuilder2.addAnimal(2, ForetOuterClass.Animal.newBuilder().addNom("test").build());


//        ForetOuterClass.Feuille.Builder feuilleBuilder;
//              ForetOuterClass.Feuille.Builder feuilleBuilder2;

        foretBuilder2.setArbre(2, foretBuilder1.getArbre(1));
        foretBuilder2.setArbre(3, foretBuilder1.getArbre(1));


       /* feuilleBuilder = foretBuilder2.getArbre(1).getFeuille(1).toBuilder();
              feuilleBuilder2 = foretBuilder2.getArbre(1).getFeuille(2).toBuilder();
            animalBuilder.setAnnee(9999);
          foretBuilder2.getArbre(1).se
*/
//        foretBuilder2.getArbre(1).getFeuilleList().set(1, feuilleBuilder2.build());

        generateBinaryFile(foretBuilder1, FILE_FORET_1);
        generateBinaryFile(foretBuilder2, FILE_FORET_2);
    }
}

用于Extratc的类,并比较每个文件中的两个对象

package javers;


import data.generated.ForetOuterClass;
import org.javers.core.Javers;
import org.javers.core.JaversBuilder;
import org.javers.core.diff.Change;
import org.javers.core.diff.Diff;
import org.javers.core.diff.ListCompareAlgorithm;

import static data.ForetDAO.readFile;


public class ComparaisonJaVers {

    private static final String FILE_FORET_1 = "foret1.txt";
    private static final String FILE_FORET_2 = "foret2.txt";

    public static void main(String[] args) {


        ForetOuterClass.Foret foret1 = readFile(FILE_FORET_1);
        ForetOuterClass.Foret foret2 = readFile(FILE_FORET_2);


        Javers javers = JaversBuilder.javers().withListCompareAlgorithm(ListCompareAlgorithm.AS_SET)/*.withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE)*/.build();

        Diff diff = javers.compare(foret1, foret2);
        diff.prettyPrint();

        for (Change change : diff.getChanges()) {
            System.out.println(change.toString());
        }


    }
}

你能帮忙吗?

0 个答案:

没有答案