개체를 인코딩하는 동안 MongoDB BSON 코덱이 사용되지 않습니다.
MongoDB 3.0.2를 사용하여 MongoDB 데이터베이스에 개체를 저장하려고 시도하고 있습니다.CodecConfigurationException
오류 메시지로 개체를 인코딩하려고 할 때
Can't find a codec for class java.time.LocalDate.
다음을 위한 코덱을 작성하고 포함했습니다.LocalDate
물건들.자세한 내용은 다음과 같습니다.
그 물건,DutyBlock
저장하려는 구성원 변수는 다음과 같습니다.
public class DutyBlock {
private LocalDate startDate;
private LocalDate endDate; //Inclusive
private int blockLength;
private double pointValue;
private ArrayList<Ra> assigned;
}
나는 다음 코덱을 작성하여 인코딩했습니다.DutyBlock
데이터베이스 내의 개체:
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));
}
}
MongoDB는 현재 지원하지 않기 때문에java.time.LocalDate class
다음 코덱을 작성하여 코드화했습니다.LocalDate
데이터베이스 내의 개체:
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);
}
}
두 개를 추가했습니다.Codec
의 (용으로 하나와 함께)Ra
타이핑)의CodecRegistry
MongoClient를 인스턴스화하는 동안 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)
.
.
}
저장을 시도합니다.ArrayList
의DutyBlock
의 일부로서의 물건.org.bson.Document
MongoDB 데이터베이스 내에 있습니다.
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.
}
그러나 다음 오류 메시지가 표시됩니다.
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)
내 코덱은 다음을 위한 것 같습니다.LocalDate
암호화를 시도할 때 사용되지 않습니다.DutyBlock
객체, 비록 내가 저장하려는 컬렉션이org.bson.Document
인에는 실제로 포함되어 있습니다.LocalDateCodec
a를 통해
System.out.println(collection.getCodecRegistry().get(LocalDate.class));
누가 왜 이런 일이 일어나는지에 대한 통찰력을 제공할 수 있습니까?
며칠 동안 연구한 끝에 해결책을 찾았습니다.
그DutyBlockCodec
에 따라 다릅니다.LocalDateCodec
(내가 만든) 인코딩/디코딩을 위해.이 종속성은 두 코덱을 동일한 코덱 레지스트리에 추가하는 것만으로는 충족되지 않습니다.해결책은 a를 통과하는 것입니다.CodecRegistry
코덱을 포함하는 개체DutyBlockCodec
에 따라 다릅니다(예: a).CodecRegistry
그 안에 포함된LocalDateCodec
) 에DutyBlockCodec
구성원 변수로 저장되는 생성자입니다.를 사용하려면LocalDateCodec
인코딩하기 위해, 나는 사용합니다.EncoderContext.encodeWithChildContext()
인코딩할 코덱, 작성기 및 요소를 전달하는 메서드입니다.추가적으로, 나는 a를 쓰는 것보다 개별적인 분야를 씁니다.Document
로서String
(내 원래 코드에서처럼).그러므로DutyBlock
코덱은 다음과 같이 표시됩니다.
public class DutyBlockCodec implements Codec<DutyBlock> {
private final CodecRegistry codecRegistry;
public DutyBlockCodec(final CodecRegistry codecRegistry) {
this.codecRegistry = codecRegistry;
}
@Override
public void encode(BsonWriter writer, DutyBlock t, EncoderContext ec) {
writer.writeStartDocument();
Codec dateCodec = codecRegistry.get(LocalDate.class);
writer.writeName("startDate");
ec.encodeWithChildContext(dateCodec, writer, t.getStartDate());
writer.writeName("endDate");
ec.encodeWithChildContext(dateCodec, writer, t.getEndDate());
writer.writeName("blockLength");
writer.writeInt32(t.getBlockLength());
writer.writeName("pointValue");
writer.writeDouble(t.getPointValue());
//Writing ArrayList of RAs
writer.writeName("assigned");
writer.writeStartArray();
for (Ra ra : t.getRasOnDuty()) {
Codec raCodec = codecRegistry.get(Ra.class);
ec.encodeWithChildContext(raCodec, writer, ra);
}
writer.writeEndArray();
writer.writeEndDocument();
}
@Override
public Class<DutyBlock> getEncoderClass() {
return DutyBlock.class;
}
@Override
public DutyBlock decode(BsonReader reader, DecoderContext dc) {
reader.readStartDocument();
Codec<LocalDate> dateCodec = codecRegistry.get(LocalDate.class);
reader.readName();
LocalDate startDate = dateCodec.decode(reader, dc);
reader.readName();
LocalDate endDate = dateCodec.decode(reader, dc);
reader.readName();
int blockLength = reader.readInt32();
reader.readName();
double pointValue = reader.readDouble();
//Reading ArrayList of RAs
reader.readName();
Codec<Ra> raCodec = codecRegistry.get(Ra.class);
ArrayList<Ra> rasOnDuty = new ArrayList<>();
reader.readStartArray();
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
rasOnDuty.add(raCodec.decode(reader, dc));
}
reader.readEndArray();
reader.readEndDocument();
return new DutyBlock(startDate, endDate, blockLength, pointValue, rasOnDuty);
}
}
DutyBlockCodec
다른 코덱에 따라 다르므로 다음이 필요합니다.CodecRegistry
생성자에게 전달됩니다.내가 생각하기에 그것을 만드는 것은 가능합니다.CodecRegistry
와 함께LocalDateCodec
그리고 나서 이것을 논쟁으로 넘깁니다.DutyBlockCodec
의 생성자를 생성한 다음 다른 생성자를 생성합니다.CodecRegistry
둘 다 포함하는LocalDateCodec
그리고.DutyBlockCodec
이것은 다소 혼란스럽고, MongoDB는 기능을 제공합니다.CodecProvider
이 과정을 용이하게 하기 위해.
사용CodecProvider
인터페이스, 나는 다음과 같이 썼습니다.DutyBlockCodecProvider
public class DutyBlockCodecProvider implements CodecProvider {
@Override
public <T> Codec<T> get(Class<T> type, CodecRegistry cr) {
if (type == DutyBlock.class) {
return (Codec<T>) new DutyBlockCodec(cr);
}
return null;
}
}
는 이 습다니했을 했습니다.CodecProviders
MongoDB를 합니다.CodecRegistries.fromProviders()
방법.
CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
CodecRegistries.fromCodecs(new LocalDateCodec()),
CodecRegistries.fromProviders(
new RaCodecProvider(),
new DutyBlockCodecProvider(),
new ScheduledDutyCodecProvider()),
MongoClient.getDefaultCodecRegistry());
MongoClientOptions options = MongoClientOptions.builder()
.codecRegistry(codecRegistry).build();
mongoClient = new MongoClient(new ServerAddress(), options);
db = mongoClient.getDatabase("DutySchedulerDB");
이 프로젝트에 대한 제 소스 코드는 https://github.com/desrepair/DutyScheduler 에서 찾을 수 있습니다. 저는 사람들이 가질 수 있는 어떤 질문에도 대답할 수 있습니다.
mongo java 드라이버 버전 3.7 이후,Instant
,LocalDate
그리고.LocalDateTime
을 더 이상가 없습니다더 이상 자신의 코덱을 코딩할 필요가 없습니다.
언급URL : https://stackoverflow.com/questions/30569228/mongodb-bson-codec-not-being-used-while-encoding-object
'programing' 카테고리의 다른 글
git을 위한 Unity 프로젝트를 준비하는 방법(단계별)? (0) | 2023.07.07 |
---|---|
gitignore가 폴더를 무시하지 않음 (0) | 2023.07.07 |
MongoDB 속성 이름을 줄일 가치가 있습니까? (0) | 2023.07.07 |
WP_REST_Request에서 쿼리 매개 변수에 액세스할 수 없는 이유는 무엇입니까? (0) | 2023.07.07 |
github에서 "실제" 커밋 날짜/시간 참조(시간/일) (0) | 2023.07.07 |