java - MongoDB DBRef 列表在 Spring Boot 中返回 null

标签 java mongodb spring-boot nosql

我正在尝试使用 Spring Boot 在 MongoDB 中创建数据库。我想创建两个集合,一个 DbConnections 集合和一个 Configuration 集合。我想要做的是 DbConnections 集合中的每个连接都有它自己的配置,就像使用外键的 SQL 引用一样。我尝试使用 @DBRef 注释来执行此操作,如下所示:

@Document(collection = "connections")
public class DbConnection {
    @Transient
    public static final String SEQUENCE_NAME = "connection_sequence";
    @Id
    private long id;
    private String username;
    private String password;
    private String connectionUrl;
    private long fkIdUsuario;
    @DBRef(db = "configurations")
    private List<Configuration> configurations;

    public DbConnection() {
    }

    public DbConnection(String username, String password, String connectionUrl) {
        this.username = username;
        this.password = password;
        this.connectionUrl = connectionUrl;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public List<Configuration> getConfigurations() {
        return configurations;
    }

    public void setConfigurations(List<Configuration> configurations) {
        this.configurations = configurations;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getConnectionUrl() {
        return connectionUrl;
    }

    public void setConnectionUrl(String connectionUrl) {
        this.connectionUrl = connectionUrl;
    }

    public long getFkIdUsuario() {
        return fkIdUsuario;
    }

    public void setFkIdUsuario(long fkIdUsuario) {
        this.fkIdUsuario = fkIdUsuario;
    }
}

和配置类:

@Document(collection = "configurations")
public class Configuration {
    @Transient
    public static final String SEQUENCE_NAME = "config_sequence";
    @Id
    private long id;
    private int fkIdConnection;
    private String name;
    private String query;
    private BasicDBObject values;
    private BasicDBObject result;

    public Configuration() {
    }

    public Configuration(long id, int fkIdConnection, String name, String query, BasicDBObject values, BasicDBObject result) {
        this.id = id;
        this.fkIdConnection = fkIdConnection;
        this.name = name;
        this.query = query;
        this.values = values;
        this.result = result;
    }

    public int getFkIdConnection() {
        return fkIdConnection;
    }

    public void setFkIdConnection(int fkIdConnection) {
        this.fkIdConnection = fkIdConnection;
    }

    public Map getValues(){
        if(null != values){
            return values.toMap();
        }
        return null;
    }

    public void setValues(){
        this.values = new BasicDBObject(values);
    }

    public Map getResult(){
        if(null != result){
            return result.toMap();
        }
        return null;
    }

    public void setResult(){
        this.result = new BasicDBObject(result);
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getQuery() {
        return query;
    }

    public void setQuery(String query) {
        this.query = query;
    }
}

我将这样的数据保存在 Controller 中: 对于 DbConnectionsController:

@PostMapping(value = "/conexion")
    public DbConnection addConnection(@RequestBody DbConnectionModel dbConnectionModel){
        DbConnection dbConnection = new DbConnection(dbConnectionModel.getUsername(), dbConnectionModel.getPassword(), dbConnectionModel.getConnectionUrl());
        dbConnection.setFkIdUsuario(getIdUsuario());
        return dbConnectionRepository.save(dbConnection);
    }

配置 Controller 保存方法:

@PostMapping
    public Configuration agregarConfiguracion(@RequestBody Configuration configuration){
        configuration.setId(sequenceGeneratorService.generateSequence(Configuration.SEQUENCE_NAME));

        return configurationRepository.save(configuration);
    }

现在,当我保存 Connection 时,它在 mongo 对象中没有字段 configurations,而当我创建新的 Configuration 时code> 它仍然没有在 DbConnection 中显示它。我尝试使用 GET 请求获取 DbConnections 对象,但是 configurations 字段DbConnections 显示为 null。为什么会发生这种情况以及如何解决?

最佳答案

我在 DBRef 返回空值数组时遇到了类似的问题。帮助我诊断的几个步骤:

1) 您的 2 个集合连接配置 是否保存在 2 个单独的数据库中?如果没有,您需要删除@DBRef后面的(db = "configurations")

@DBRef
private List<Configuration> configurations;

2) 直接连接数据库时能否找到对象?我使用 Robot 3T,这是一个 GUI 工具,可以直接查看 Mongo DB 以检查保存的数据的形状。确保您的连接设置正确,您还应该看到每个连接配置,如下所示:

configurations: [
  {
    "$ref": "configurations",
    "$id": ObjectId("asdfadsgasdfasdfa")
  }
]

3) 您可以单步进入 org.springframework.data.mongodb.core.convert.DefaultDbRefResolver 类的 fetch() 方法。 (我使用的是 springboot 2.1.6.RELEASE 以及同一版本的 spring-boot-starter-data-mongodb 依赖项)

@Override
    public Document fetch(DBRef dbRef) {

        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Fetching DBRef '{}' from {}.{}.", dbRef.getId(),
                    StringUtils.hasText(dbRef.getDatabaseName()) ? dbRef.getDatabaseName() : mongoDbFactory.getDb().getName(),
                    dbRef.getCollectionName());
        }

        StringUtils.hasText(dbRef.getDatabaseName());
        return getCollection(dbRef).find(Filters.eq("_id", dbRef.getId())).first();
    }

确保dbRef的所有属性(即collectionName、db、id)都正确,否则将无法找到相关对象。

关于java - MongoDB DBRef 列表在 Spring Boot 中返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57021914/

相关文章:

java - 在外部 tomcat 上运行 war 文件时禁止将 appName 添加到 url

java - 委托(delegate)模式的目的是什么?

java - 观察者模式建议

javascript - Meteor.js 可以用 Cassandra 代替 MongoDB 吗?

MongoDB 从 3.2 转储,使用 3.4 恢复,错误索引安全 = null

java - 在后台运行 Spring-retry

spring - 添加 expire 到 Spring Security remember me cookie

java - 递归与堆栈实现。为什么递归返回 StackOverflow 而 Stack 不返回?

java - 数组的标准正态分布

javascript - 在单个内部属性上查找匹配的数组内容和长度