Java 如何在没有@BsonDiscriminator的情况下使用mongodb和lombook中的不可变对象

Java 如何在没有@BsonDiscriminator的情况下使用mongodb和lombook中的不可变对象,java,mongodb,lombok,Java,Mongodb,Lombok,我尝试在MongoDB和Lombok中使用不可变对象。我找到了问题的解决方案,但它需要从中编写额外的代码,但我需要使用Bson注释并创建一个构造函数,其中通过注释描述字段。但如果我user@allargsconstuctor捕获异常:“找不到‘user’的公共构造函数”,因为我不能将默认构造函数用于最终字段。我想我可以正确地自定义CodecRegistry,这个示例也可以正常工作,但我无法在docs、google和Stackoverflow中找到解决方案 有办法解决这个问题吗? @Data @B

我尝试在MongoDB和Lombok中使用不可变对象。我找到了问题的解决方案,但它需要从中编写额外的代码,但我需要使用Bson注释并创建一个构造函数,其中通过注释描述字段。但如果我user@allargsconstuctor捕获异常:“找不到‘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;
    }

}
公共类示例MongoDB{
公共静态void main(字符串[]args){
final MongoClient MongoClient=MongoClients.create();
最终MongoDatabase数据库=mongoClient.getDatabase(“db”);
database.drop();
final CodecRegistry pojoCodecRegistry=fromRegistries(MongoClientSettings.getDefaultCodecRegistry(),
fromProviders(PojoCodecProvider.builder().automatic(true.build());
最终MongoCollection用户=database.getCollection(“users”,User.class.),WithCodeRegistry(PojoCodeRegistry);
users.insertMany(新示例mongodb().getRandomUsers());
System.out.println(“更新前:”);
users.find(新文档(“角色”、“管理员”)).iterator().foreachs(
System.out::println
);
System.out.println(“更新后:”);
users.updateMany(eq(“角色”、“管理员”)、set(“角色”、“来宾”);
users.find(新文档(“角色”、“来宾”)).iterator().foreachs(
System.out::println
);
}
公共列表getRandomUsers(){
最终ArrayList用户=新ArrayList();
对于(int i=0;i<15;i++){
users.add(
User.builder()
.login(“日志”+i)
.名称(“名称”+i)
.通过(“通过”+i)
.角色(
(i%2==0)?User.Role.ADMIN:User.Role.User
).build()
);
}
返回用户;
}
}
这应该有效(它对我有效):

然后在
lombok.config
中添加这些(在您的模块/项目目录中):

另外一条建议是,如果要使用PojoCodec自动转换为POJO,请保留
\u id
,这将节省很多麻烦

@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.addLombokGeneratedAnnotation=true
lombok.anyConstructor.addConstructorProperties=true
lombok.copyableAnnotations += org.bson.codecs.pojo.annotations.BsonProperty
lombok.copyableAnnotations += org.bson.codecs.pojo.annotations.BsonId