使用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());
}
}
}
你能帮忙吗?