Der MongoDB BSON-Codec wird beim Codieren des Objekts nicht verwendet
Ich versuche, zu speichern ein Objekt in einer MongoDB-Datenbank (mit MongoDB 3.0.2) und bin immer ein CodecConfigurationException
beim Versuch zu Kodieren, das Objekt mit der Fehlermeldung
Can't find a codec for class java.time.LocalDate.
Habe ich geschrieben und enthalten einen codec für die LocalDate
Objekte. Details Folgen.
Objekt DutyBlock
bin, dass ich zu speichern versucht hat, diese member-Variablen:
public class DutyBlock {
private LocalDate startDate;
private LocalDate endDate; //Inclusive
private int blockLength;
private double pointValue;
private ArrayList<Ra> assigned;
}
Schrieb ich Folgendes codec zum Kodieren des DutyBlock
Objekte innerhalb der Datenbank:
public class DutyBlockCodec implements Codec<DutyBlock> {
@Override
public void encode(BsonWriter writer, DutyBlock t, EncoderContext ec) {
Document document = new Document();
document.append("startDate", t.getStartDate());
document.append("endDate", t.getEndDate());
document.append("blockLength", t.getBlockLength());
document.append("pointValue", t.getPointValue());
document.append("assigned", t.getRasOnDuty());
writer.writeString(document.toJson()); //Line 27 in the error message.
}
@Override
public Class<DutyBlock> getEncoderClass() {
return DutyBlock.class;
}
@Override
public DutyBlock decode(BsonReader reader, DecoderContext dc) {
String json = reader.readString();
return new DutyBlock(Document.parse(json));
}
}
Da MongoDB derzeit keine Unterstützung für die java.time.LocalDate class
habe ich Folgendes geschrieben-codec zum Kodieren des LocalDate
Objekte innerhalb der Datenbank:
public class LocalDateCodec implements Codec<LocalDate> {
@Override
public void encode(BsonWriter writer, LocalDate t, EncoderContext ec) {
writer.writeString(t.toString());
}
@Override
public Class<LocalDate> getEncoderClass() {
return LocalDate.class;
}
@Override
public LocalDate decode(BsonReader reader, DecoderContext dc) {
String date = reader.readString();
return LocalDate.parse(date);
}
}
Habe ich die beiden Codec
's (zusammen mit einer für die Ra
- Typ) auf der CodecRegistry
am MongoClient Ebene während der Instanziierung des MongoClient.
public class DutyScheduleDB {
private MongoClient mongoClient;
private MongoDatabase db;
public DutyScheduleDB() {
CodecRegistry codecRegistry =
CodecRegistries.fromRegistries(
CodecRegistries.fromCodecs(new LocalDateCodec(), new DutyBlockCodec(), new RaCodec()),
MongoClient.getDefaultCodecRegistry());
MongoClientOptions options = MongoClientOptions.builder()
.codecRegistry(codecRegistry).build();
mongoClient = new MongoClient(new ServerAddress(), options);
db = mongoClient.getDatabase("DutySchedulerDB");
}
. (More code not shown)
.
.
}
Ich versuche zu speichern ArrayList
von DutyBlock
Objekte als Teil eines org.bson.Document
innerhalb der MongoDB-Datenbank.
public void storeScheduledCalendar(String id,
String calendarName,
ArrayList<DutyBlock> cal) {
//Access collection of scheduled calendars.
MongoCollection collection = db.getCollection("ScheduledCalendars");
//Query parameter is uuid + calendarName.
Document doc = new Document("name", id + calendarName);
doc.append("dutyBlocks", cal);
//Insert doc to collection.
collection.insertOne(doc); //Line 59 in the error message.
}
Aber ich bin mit diese Fehlermeldung:
Exception in thread "main" org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.time.LocalDate.
at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:37)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:174)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:189)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:131)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45)
at org.bson.Document.toJson(Document.java:294)
at org.bson.Document.toJson(Document.java:268)
at org.bson.Document.toJson(Document.java:255)
at SchedulingHeuristic.DutyBlockCodec.encode(DutyBlockCodec.java:27)
at SchedulingHeuristic.DutyBlockCodec.encode(DutyBlockCodec.java:16)
at org.bson.codecs.EncoderContext.encodeWithChildContext(EncoderContext.java:91)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:175)
at org.bson.codecs.DocumentCodec.writeIterable(DocumentCodec.java:197)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:170)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:189)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:131)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
at com.mongodb.connection.InsertCommandMessage.writeTheWrites(InsertCommandMessage.java:99)
at com.mongodb.connection.InsertCommandMessage.writeTheWrites(InsertCommandMessage.java:43)
at com.mongodb.connection.BaseWriteCommandMessage.encodeMessageBody(BaseWriteCommandMessage.java:112)
at com.mongodb.connection.BaseWriteCommandMessage.encodeMessageBody(BaseWriteCommandMessage.java:35)
at com.mongodb.connection.RequestMessage.encode(RequestMessage.java:132)
at com.mongodb.connection.BaseWriteCommandMessage.encode(BaseWriteCommandMessage.java:89)
at com.mongodb.connection.WriteCommandProtocol.sendMessage(WriteCommandProtocol.java:170)
at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.java:73)
at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:66)
at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:37)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:155)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:219)
at com.mongodb.connection.DefaultServerConnection.insertCommand(DefaultServerConnection.java:108)
at com.mongodb.operation.MixedBulkWriteOperation$Run$2.executeWriteCommandProtocol(MixedBulkWriteOperation.java:416)
at com.mongodb.operation.MixedBulkWriteOperation$Run$RunExecutor.execute(MixedBulkWriteOperation.java:604)
at com.mongodb.operation.MixedBulkWriteOperation$Run.execute(MixedBulkWriteOperation.java:363)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:148)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:141)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:186)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:177)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:141)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:72)
at com.mongodb.Mongo.execute(Mongo.java:747)
at com.mongodb.Mongo$2.execute(Mongo.java:730)
at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:482)
at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:277)
at DutyScheduleDB.storeScheduledCalendar(DutyScheduleDB.java:59)
at DutyScheduleDB.main(DutyScheduleDB.java:106)
Scheint es, dass mein codec für LocalDate
nicht verwendet werden, wenn Sie versuchen zu codieren DutyBlock
Objekte, aber ich habe festgestellt, dass die Sammlung, die ich bin versucht zu speichern, die org.bson.Document
im tut in der Tat enthalten die LocalDateCodec
über eine
System.out.println(collection.getCodecRegistry().get(LocalDate.class));
Können jeder kann einen Einblick, warum dies passiert ist?
InformationsquelleAutor der Frage desrepair | 2015-06-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nach mehreren Tagen recherche habe ich herausgefunden, eine Lösung.
Den
DutyBlockCodec
hängt von derLocalDateCodec
(die ich erstellt), um zu Kodieren/Dekodieren. Diese Abhängigkeit ist nicht zufrieden, einfach durch hinzufügen von zwei codecs in den gleichen codec registry. Die Lösung ist ein pass einCodecRegistry
- Objekt mit den codecs, dieDutyBlockCodec
abhängt (z.B. eineCodecRegistry
mit in es dieLocalDateCodec
) derDutyBlockCodec
's Konstruktor, der das gespeichert ist, als eine member-variable. Um dieLocalDateCodec
zum codieren benutze ich dieEncoderContext.encodeWithChildContext()
Methode übergeben, die den codec, Schriftsteller und element zu Kodieren. Darüber hinaus Schreibe ich einzelne Felder, sondern schreiben eineDocument
alsString
(wie in meinem original code). So ist dieDutyBlock
codec landet so Aussehen:DutyBlockCodec
hängt von einem anderen codec, und so erfordertCodecRegistry
übergeben zu werden, auf seinen Konstruktor. Ich glaube zwar, dass es möglich ist, erstellen Sie eineCodecRegistry
mit derLocalDateCodec
, dann übergeben Sie dieses als argument zuDutyBlockCodec
's Konstruktor, dann erstellen Sie einen anderenCodecRegistry
mitLocalDateCodec
undDutyBlockCodec
ist dies eher verwirrend, und MongoDB bietet eine Funktionalität, dieCodecProvider
um diesen Prozess zu erleichtern.Mithilfe der
CodecProvider
- Schnittstelle, schrieb ich eineDutyBlockCodecProvider
Fügte ich diese
CodecProviders
auf die MongoDB-Client mit derCodecRegistries.fromProviders()
Methode.Mein source-code für dieses Projekt finden Sie unter https://github.com/desrepair/DutyScheduler
Ich bin offen für die Beantwortung von Fragen, die Menschen haben können.
InformationsquelleAutor der Antwort desrepair