【问题标题】:How work with immutable object in mongodb and lombook without @BsonDiscriminator如何在没有@BsonDiscriminator 的情况下在 mongodb 和 lombook 中使用不可变对象
【发布时间】:2020-02-07 14:59:03
【问题描述】:

我尝试在 MongoDB 和 Lombok 中使用不可变对象。我找到了解决问题的方法,但它需要从 docs 编写额外的代码,但我需要使用 Bson 注释并创建一个构造函数,其中通过注释描述字段。但是,如果我使用@AllArgsConstructor 捕获异常:“找不到'User' 的公共构造函数”,因为我不能使用带有最终字段的默认构造函数。我认为我可以正确自定义 CodecRegistry 并且该示例将正常工作,但我无法在 docs、google 和 Stackoverflow 中找到解决方案。

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

@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;
    }

}

【问题讨论】:

    标签: java mongodb lombok


    【解决方案1】:

    这应该有效(对我有用):

    @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,这样会省去很多麻烦。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 2011-05-06
      相关资源
      最近更新 更多