【问题标题】:Can´t create entity in MongoDB无法在 MongoDB 中创建实体
【发布时间】:2017-01-17 14:20:59
【问题描述】:

我是 MongoDB 的新手,如果问题是基本的,很抱歉。

我正在尝试让一个基本的 CRUD 与 Java 基本对象 (POJO) 一起使用,但是此代码失败了。 (这样做的正确方法是什么?我认为它可能接近这个):

BasicDBObject document = new BasicDBObject();
document.put("name", user);
dbCollection.insert(document);

这是我收到的消息:

Exception in thread "main" java.lang.IllegalArgumentException: can't serialize class entities.users.NormalUser
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:270)
    at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:174)
    at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:120)
    at com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:27)
    at com.mongodb.OutMessage.putObject(OutMessage.java:289)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:261)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:226)
    at com.mongodb.DBCollection.insert(DBCollection.java:75)
    at com.mongodb.DBCollection.insert(DBCollection.java:59)
    at com.mongodb.DBCollection.insert(DBCollection.java:104)
    at repositories.UsersRepository.createUser(UsersRepository.java:53)
    at repositories.UsersRepository.main(UsersRepository.java:90)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

【问题讨论】:

  • 能否请您添加一些用户类/变量定义的详细信息?
  • @notionquest 当然,我会尽快更新问题,谢谢
  • @notionquest 你可以在这里查看它们。如果您需要更多信息,请告诉我stackoverflow.com/questions/39397029/…
  • Gender 和 Role 属性可能会产生序列化问题。请问您可以尝试插入没有这两个属性的文档以进行测试吗?
  • @notionquest 我摆脱了这些属性,但问题仍然存在

标签: java mongodb pojo nosql


【解决方案1】:

下面是对这个问题的详细分析:-

看起来像 "lombok" 库在编译期间添加了样板代码(即属性的 getter 和 setter 方法)。我在执行程序时观察到两种行为。

1) Eclipse 行为:-

当我通过 IDE(例如 eclipse)运行程序时,没有生成“getter”和“setter”方法。运行主类时出现序列化错误。我已经反编译了 User 和 NormalUser 类并检查了内容。它没有“getter”和“setter”方法。

Online Java Decompiler

2) Maven 行为:-

我已使用 maven 命令构建项目并检查了 User 和 NormalUser 类。这次我可以看到正在生成的样板代码。我已经执行了我的 Main 类,它运行良好。

解决方案:-

MongoClient client = new MongoClient();
        MongoDatabase database = client.getDatabase("localhost");
        MongoCollection<Document> normalUserCollection = database.getCollection("normaluser");

        User normalUser = new NormalUser("jack", "mike", "US", "dni", "123", Gender.MALE);

        Document document = new Document();
        document.put("user", document.parse(new ObjectMapper().writeValueAsString(normalUser)));

使用的 Mongo Java 驱动程序:-

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.2.2</version>
</dependency>
<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.5</version>
        </dependency>

输出:-

文档已成功插入到 MongoDB 集合中。

{
    "_id" : ObjectId("57d2e4134c1c7b287cde1d30"),
    "user" : {
        "surname" : "mike",
        "address" : "US",
        "dni" : "dni",
        "bankAccount" : "123",
        "admin" : false,
        "name" : "jack",
        "gender" : "MALE"
    }
}

【讨论】:

  • 非常感谢您提供如此详细的回复。最后,我设法让它以稍微不同的方式工作。您能否让我知道“writeValueAsString”的依赖关系?再次感谢朋友。
【解决方案2】:

尝试使用 MongoTemplate。使用此模板将java对象保存在mongodb中,它将以文档形式创建。

https://www.mkyong.com/mongodb/spring-data-mongodb-insert-document/

示例

MongoTemplate mongoTemplate = new MongoTemplate(new MongoClient("<server>"),"<db name>");

User user = new NormalUser();
mongoTemplate.save(user, "<collection>");

【讨论】:

  • 能否请您添加代码?我没有使用 Spring,而是 JAX RS。
【解决方案3】:

您不能简单地使用 mongo java 驱动程序序列化应用程序中的每个类。要么,你坚持使用 JSON 文档及其支持的数据类型(基本上是字符串、各种数字、布尔值、日期),要么为你的类编写一个自定义编解码器,以便内部 Bson 转换可以使用它。

不幸的是,我发现的唯一链接是德语的基本示例:https://dev-tek.de/lexicon/Entry/64-MongoDB-Anleitung-Custom-codecs-mit-Hilfe-des-DocumentCodecs/ - 但也许代码有助于理解。

关于评论的附录:

基本上,您可以按照以下方式手动进行转换:

Document doc = new org.bson.Document();
doc.put("userName", user.getName());
doc.put("userId", user.getID());
// ... or whatever your user object looks like
// and then:
dbCollection.insert(doc);

然后,您可以尝试将您的对象转换为 JSON 的外部编码库,例如 Jackson,在此问题的答案中有详细说明:Converting Java objects to JSON with Jackson

一旦有了 JSON 字符串,就可以通过

将其转换为 org.bson.Document
org.bson.Document.parse(jsonString)

并将其写入数据库。

【讨论】:

  • 谢谢。您能否添加如何将它们转换为 JSON 的代码?
猜你喜欢
  • 1970-01-01
  • 2015-09-15
  • 2019-11-13
  • 2016-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
相关资源
最近更新 更多