【发布时间】:2019-08-13 18:16:04
【问题描述】:
我了解如何使用 MongoDB Java 驱动程序来读取和存储 POJO 的当我们知道我们正在使用的特定类型。在我正在处理的项目中,编解码器提供程序(以及编解码器注册表)是由通过属性传入的类名构建的(有一些硬编码值)。这支持例如仅在进行测试(JUnit)时注销某些消息。
问题是我无法确定如何使用 MongoCollection 使用这种类型。下面是一个基于实际问题的玩具问题(我们有一个通用的“消息”接口,我们希望记录的所有 POJO 都实现该接口。日志记录函数接受该“消息”接口的对象并需要将其插入集合)。
首先我们有我们的界面:
public interface MyInterface {
int getX();
}
简单的实现:
public class ImplA implements MyInterface {
public int getX(){return 1;}
}
然后是使用它们的代码:
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;
import org.bson.codecs.pojo.ClassModel;
import org.bson.codecs.pojo.PojoCodecProvider;
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
public class Main {
public static void main(String[] args){
new Main().run();
}
public void run(){
MongoClient client = MongoClients.create("mongodb://localhost:27018");
MongoDatabase db = client.getDatabase("db1").withCodecRegistry(fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
fromProviders(PojoCodecProvider.builder().register(
ClassModel.builder(MyInterface.class).enableDiscriminator(true).build(),
ClassModel.builder(ImplA.class).enableDiscriminator(true).build()
).build())
));
MyInterface obj1 = new ImplA();
db.getCollection("ImplA",ImplA.class).insertOne((ImplA) obj1);
db.getCollection("ImplA",obj1.getClass()).insertOne(obj1);
db.getCollection("ImplA",Object.class).insertOne(obj1);
}
}
当第一个插入编译时,第二个失败并出现此错误:
Error:Error:line (42)java: 不兼容的类型:Main.MyInterface 不能转换为 capture#1 of ?扩展 Main.MyInterface
在我看来这个功能应该是可能的,因为 MongoCollection 肯定有关于类型的信息。传入的对象具有某种类型,我想要该类型的集合并插入它。如果第二个 insertOne 被注释掉,则代码编译。驱动程序抛出一个异常,说 Object 没有编解码器;因此,它肯定是从给定的集合中确定要使用的编解码器。
更新:我曾尝试使用 getClass.cast 进行各种强制转换,各种泛型组合,但这里有一个可行的选项:
MyInterface obj1 = new ImplA();
Class<MyInterface> myC = (Class<MyInterface>) Class.forName(obj1.getClass().getName());
db.getCollection("ImplA",myC).insertOne(obj1);
这会引发类未找到异常,并且看起来不必要地复杂。
【问题讨论】:
标签: java mongodb generics pojo mongodb-java