当前位置: 首页 > 知识库问答 >
问题:

在mongodb和lombook中如何使用不变对象而不使用@bsonDiscriminator

酆鸿彩
2023-03-14

有没有办法解决这个问题?

@Data
@Builder(builderClassName = "Builder")
@Value
@BsonDiscriminator
public class User {
    private final ObjectId id;
    private final String name;
    private final String pass;
    private final String login;
    private final Role role;

    @BsonCreator
    public User(@BsonProperty("id") final ObjectId id,
                @BsonProperty("name") final String name,
                @BsonProperty("pass") final String pass,
                @BsonProperty("login") final String login,
                @BsonProperty("role") final Role role) {
        this.id = id;
        this.name = name;
        this.pass = pass;
        this.login = login;
        this.role = role;
    }

    @AllArgsConstructor
    public enum Role {
        USER("USER"),
        ADMIN("ADMIN"),
        GUEST("GUEST");

        @Getter
        private String value;
    }

    public static class Builder {

    }

}

MongoDB的示例,我在其中创建、保存并更新用户:

public class ExampleMongoDB {


    public static void main(String[] args) {
        final MongoClient mongoClient = MongoClients.create();
        final MongoDatabase database = mongoClient.getDatabase("db");
        database.drop();
        final CodecRegistry pojoCodecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(),
            fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        final MongoCollection<User> users = database.getCollection("users", User.class).withCodecRegistry(pojoCodecRegistry);
        users.insertMany(new ExampleMongoDB().getRandomUsers());
        System.out.println("Before updating:");
        users.find(new Document("role", "ADMIN")).iterator().forEachRemaining(
            System.out::println
        );
        System.out.println("After updating:");
        users.updateMany(eq("role", "ADMIN"), set("role", "GUEST"));
        users.find(new Document("role", "GUEST")).iterator().forEachRemaining(
            System.out::println
        );
    }


    public List<User> getRandomUsers() {
        final ArrayList<User> users = new ArrayList<>();
        for (int i = 0; i < 15; i++) {
            users.add(
                User.builder()
                    .login("log" + i)
                    .name("name" + i)
                    .pass("pass" + i)
                    .role(
                        (i % 2 == 0) ? User.Role.ADMIN : User.Role.USER
                    ).build()
            );
        }
        return users;
    }

}

共有1个答案

公孙鸿才
2023-03-14

这应该行得通(对我也行得通):

@Builder(builderClassName = "Builder")
@Value
@AllArgsConstructor(onConstructor = @__(@BsonCreator))
@BsonDiscriminator
public class User {
   @BsonId
   private final ObjectId _id;

   @BsonProperty("name")
   private final String name;

   @BsonProperty("pass")
   private final String pass;

   @BsonProperty("login")
   private final String login;

   @BsonProperty("role")
   private final Role role;
}

然后在lombok.config添加以下内容(在模块/项目目录中):

lombok.addLombokGeneratedAnnotation=true
lombok.anyConstructor.addConstructorProperties=true
lombok.copyableAnnotations += org.bson.codecs.pojo.annotations.BsonProperty
lombok.copyableAnnotations += org.bson.codecs.pojo.annotations.BsonId

还有一个建议,如果您打算使用PojoCodec自动转换到POJO,请保留_id,这样会省去很多麻烦。

 类似资料:
  • 由于这是一个热门的话题,这些天,我无法理解某些概念。请原谅,如果我听起来很愚蠢,但当我试图创建不可变对象时,我发现大多数帖子如下 null null 此测试用例失败并打印Cassandra。 如果我做错了什么让我知道。

  • 问题内容: 我想做的是从而不是从Volley库中使用一些数据。 以下是用于从服务器中获取JSON对象的代码。 我试图改变到后改为。但这并没有解决。 问题答案: 中的url 不是可选的,并且JSONObject参数用于将带有请求的参数发布到url。 从文档中:http : //afzaln.com/volley/com/android/volley/toolbox/JsonObjectRequest

  • 我们正在使用不可变框架来生成所有的DTO。现在我们想用MapStruct将这些对象映射到另一个对象。但是生成的DTO是不可变的,没有设置器和构造器,对应于构建器模式。它们只通过静态-方法访问的相应生成器来填充。 相反,我们尝试将DTO1映射到DTO2.Builder,如果mapstruct能够识别生成器中的setter,那么它就可以工作,但是它们没有void返回类型,而是返回生成器本身,以便进行流

  • 我正在使用JAXB从XSD文件创建Java对象。我正在创建不可变包装器来隐藏由JAXB生成的对象(之前我更新了JAXB对象,以实现不可变接口并将接口返回给客户机。但意识到改变自动生成的类是不好的,因此使用包装器) 目前,我正在将这些不可变的包装返回到客户端应用程序。是否有任何选项,使自动生成的类将是不可变的,并避免创建不可变包装器的额外工作。任何其他方法都是鼓励的。 谢谢

  • 问题内容: 我有以下请求处理程序 和以下mongodb反应式存储库 问题在于执行该方法后,对象中没有任何更改。我设法解决了这个问题,但是我不知道为什么在其他存储库中进行的第一个保存有效,而这个无效。为什么要这样做? 问题答案: 除非有人订阅了反应式发布者,否则什么都不会发生。这就是为什么当您使用block()时它开始起作用的原因。如果您需要调用数据库并在另一个数据库请求中使用结果,而不是使用诸如m

  • 我需要在没有MediaExtractor的情况下使用MediaCodec,并且我正在使用FileInputStream读取文件。目前它不工作,它正在屏幕上显示一个绿色的加扰图像。 如果我使用MediaExtractor,一切都正常。我在使用MediaExtractor时通过查看MediaFormat获得SPS/PPS值。如果我删除下面的部分,屏幕上不会显示任何内容。 我错过了什么?在没有Media