使用 java 的 mongo 驱动程序保存接口对象列表 [英] Save List of interface objects using mongo driver for java
本文介绍了使用 java 的 mongo 驱动程序保存接口对象列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个包含 Resource
列表的 POJO,它是 ResourceType1
和 ResourceType2
I have a POJO that has a list of Resource
s which is the interface of ResourceType1
and ResourceType2
public class MyPojo {
private List<Resource>;
....
}
public interface Resource {
public String getResourceId();
}
public ResourceType1 implements Resource{
public String getResourceId(){ return resourceType1Id; }
public String doOtherResourceType1SpecificStuff(){}
}
public ResourceType2 implements Resource{
public String getResourceId(){ return resourceType2Id; }
public boolean doOtherResourceType2SpecificStuff(){}
}
public class Database {
CodecRegistry pojoCodecRegistry = fromRegistries(
MongoClient.getDefaultCodecRegistry(),
fromProviders(PojoCodecProvider.builder()
.register(MyPojo.class)
.register(ResourceType1.class)
.register(ResourceType2.class)
.register(Resource.class)
.automatic(true).build()));
}
我在我的数据库类中使用 mongodb-driver-core-3.5.0
来保存和检索 myPojo
的.
Im using mongodb-driver-core-3.5.0
in my Database class to save and retrieve myPojo
's.
我在保存时出错并创建了文档,但是当我使用 MongoCompass 检查保存的文档时,资源列表为空.
Im get this on error on save and the docuement is created, but the list of resources is empty when I use MongoCompass to inspect the saved document.
这是错误:
org.bson.codecs.configuration.CodecConfigurationException: Failed to decode 'resources'. An exception occurred when decoding using the AutomaticPojoCodec.
Decoding into a 'Resource' failed with the following exception:
Cannot find a public constructor for 'Resource'.
A custom Codec or PojoCodec may need to be explicitly configured and registered to handle this type.
at org.bson.codecs.pojo.PojoCodecImpl.decodePropertyModel(PojoCodecImpl.java:173)
at org.bson.codecs.pojo.PojoCodecImpl.decodeProperties(PojoCodecImpl.java:149)
at org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:103)
at org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:107)
...
我过去也遇到过类似的问题,我刚刚写了一个 MyPojoWrapper
在那里我手动编组和解组所有内容.但是我必须相信这更常见,并且有一个我没有看到的简单解决方案.提前致谢.
推荐答案
public class MongoInterfaceTest {
private static MongoClient mongoClient;
static {
init();
}
public static void init() {
try {
ClassModel<User> userClassModel = ClassModel.builder(User.class).enableDiscriminator(true).build();
ClassModel<JavaUser> javaUserClassModel = ClassModel.builder(JavaUser.class).enableDiscriminator(true).build();
ClassModel<PythonUser> pythonUserClassModel = ClassModel.builder(PythonUser.class).enableDiscriminator(true).build();
ClassModel<TestUser> testUserClassModel = ClassModel.builder(TestUser.class).enableDiscriminator(true).build();
CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(
PojoCodecProvider.builder()
.register(
userClassModel,
javaUserClassModel,
pythonUserClassModel,
testUserClassModel
)
.automatic(true)
.build()
)
);
mongoClient = MongoClients.create(
MongoClientSettings.builder()
.codecRegistry(pojoCodecRegistry)
.applyConnectionString(new ConnectionString(ApplictaionConfig.MONGODB_URL))
.applyToConnectionPoolSettings(builder -> {
builder.minSize(10);
})
.build()
);
} catch (Exception e) {
System.out.println("Connection mongodb failed");
throw new RuntimeException();
}
}
public static void main(String[] args) {
MongoCollection<TestUser> collection = getMongoCollection("TestUser", TestUser.class);
JavaUser javaUser = new JavaUser("a");
PythonUser pythonUser = new PythonUser("b","1");
TestUser testUser = new TestUser(javaUser.name, javaUser);
insertOne(collection, testUser);
testUser = new TestUser(pythonUser.name, pythonUser);
insertOne(collection, testUser);
Bson bson = Filters.and(Filters.eq("name", "a"));
TestUser testUser1 = findFirst(collection, bson);
System.out.println(testUser1);
System.out.println(testUser1.user.dev());
bson = Filters.and(Filters.eq("name", "b"));
testUser1 = findFirst(collection, bson);
System.out.println(testUser1);
System.out.println(testUser1.user.dev());
}
/**
* 获得collection对象
*/
public static <T> MongoCollection<T> getMongoCollection(String collectionName, Class<T> tClass) {
MongoDatabase mongoDatabase = mongoClient.getDatabase("kikuu");
MongoCollection<T> collection = mongoDatabase.getCollection(collectionName, tClass);
return collection;
}
public static <T> void insertOne(MongoCollection<T> collection, T document) {
insertMany(collection, Lists.newArrayList(document));
}
public static <T> void insertMany(MongoCollection<T> collection, List<T> documents) {
collection.insertMany(documents);
}
public static <T> T findFirst(MongoCollection<T> collection) {
return (T) collection.find().first();
}
public static <T> T findFirst(MongoCollection<T> collection, Bson bson) {
return (T) collection.find(bson).first();
}
public static interface User {
String dev();
}
public static class JavaUser implements User{
public String name;
public JavaUser() {
}
public JavaUser(String name) {
this.name = name;
}
@Override
public String dev() {
return "java";
}
@Override
public String toString() {
return "JavaUser{" +
"name='" + name + '\'' +
'}';
}
}
public static class PythonUser implements User{
public String name;
public String age;
public PythonUser() {
}
public PythonUser(String name, String age) {
this.name = name;
this.age = age;
}
@Override
public String dev() {
return "python";
}
@Override
public String toString() {
return "PythonUser{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
public static class TestUser {
public String name;
public User user;
public TestUser() {
}
public TestUser(String name, User user) {
this.name = name;
this.user = user;
}
@Override
public String toString() {
return "TestUser{" +
"name='" + name + '\'' +
", user=" + user +
'}';
}
}
}
这篇关于使用 java 的 mongo 驱动程序保存接口对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文