【问题标题】:Spring data mongodb @DBRef listSpring Data mongodb @DBRef 列表
【发布时间】:2017-11-22 16:10:57
【问题描述】:

我正在尝试使用@DBRef 在模型中创建一个列表,但我无法让它工作。 这是我的用户模型:

@Data
@Document
public class User {

    @Id
    @JsonSerialize(using = ToStringSerializer.class)
    private ObjectId id;

    @Indexed(unique = true)
    @NotBlank
    private String email;

    @NotBlank
    private String name;

    @NotBlank
    private String password;

    @DBRef
    private List<Server> servers;
}

服务器型号:

@Data
@Document
public class Server {

    @Id
    @JsonSerialize(using = ToStringSerializer.class)
    private ObjectId id;

    @NotBlank
    private String name;

    @NotBlank
    private String host;
}

结构很简单,每个用户可以有多个服务器。但是当我向用户添加服务器时,会创建服务器,但服务器数组包含一个null 条目("servers" : [ null ])。所以服务器不会添加到用户。这就是我创建服务器并将其添加到用户的方式:

@PostMapping
public Mono create(@Valid @RequestBody Server server, Mono<Authentication> authentication) {
    return this.serverRepository.save(server).then(authentication.flatMap(value -> {
        User user = (User) value.getDetails();
        user.getServers().add(server);

        return userRepository.save(user);
    })).map(value -> server);
}

所以我只需创建并保存服务器,将服务器添加到用户,然后保存用户。但它不起作用。我一直有一个包含一个 null 条目的数组。

我看过这个页面:http://www.baeldung.com/cascading-with-dbref-and-lifecycle-events-in-spring-data-mongodb。但它是用于保存子文档,而不是用于链接它。它也适用于单个文档,而不适用于数组或列表。

为什么我的列表没有正确保存?

我所有的库都来自 Spring Boot 版本 2.0.0.M6

更新 从用户的服务器属性中删除@DBRef 时,服务器会被保存,但它们当然会在server 集合和每个user.servers 中双重创建。所以错误与引用有关。

【问题讨论】:

  • 你能不能把Authentication类也放上来,这样我们就可以试试我们的代码了
  • 以上代码对我有用
  • @pvpkiran Authentication接口来自spring(org.springframework.security.core.Authentication)
  • @pvpkiran 当我从用户对象编辑其他属性时它工作正常,只有服务器列表不起作用。
  • 你能检查user.getServers()是否给你返回一个列表吗?

标签: spring mongodb reactive-programming spring-webflux dbref


【解决方案1】:

经过一番谷歌搜索,我找到了答案...
https://jira.spring.io/browse/DATAMONGO-1583
https://jira.spring.io/browse/DATAMONGO-1584

反应式 mongo 不支持这一点。

【讨论】:

  • 这很奇怪。因为。我测试的方法不是通过休息调用发送它,而是硬编码值(用户、服务器和身份验证)并使用休息调用(不带参数)触发函数。但我保持了反应性代码的原样。那行得通。不确定这会如何改变行为
【解决方案2】:

实际上有一种方法可以在不使用阻塞驱动程序的情况下解决 DbRefs。是 - 引用以阻塞方式解析,但不需要第二个连接。为了实现这一点,我们必须编写自己的 DbRefResolver:NbDbRefResolver.java。在提供的解析器中有一个标志:RESOLVE_DB_REFS_BY_ID_ONLY。如果打开,则不会从数据库中解析 DbRefs,而是将它们解析为仅具有 id 的假对象。稍后以非阻塞方式填充引用取决于实现。

如果标志 RESOLVE_DB_REFS_BY_ID_ONLY 设置为 false,它将使用非阻塞驱动程序急切地解析引用,但会阻塞执行,直到解析引用。 以下是在应用程序中注册 DbRefResolver 的方法:DbConfig.kt

此处提供附件:https://jira.spring.io/browse/DATAMONGO-1584

【讨论】:

    【解决方案3】:

    我就是这样处理角色的:

      @Unwrapped(onEmpty = Unwrapped.OnEmpty.USE_NULL)
      private Collection<Role> roles;
    

    您可以在此处查看文档 (2021):https://spring.io/blog/2021/04/20/what-s-new-in-spring-data-2021-0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-31
      • 2015-10-31
      • 1970-01-01
      • 2019-11-23
      • 1970-01-01
      • 1970-01-01
      • 2021-04-03
      • 1970-01-01
      相关资源
      最近更新 更多