Spring Mongo DB @DBREF

У меня проблемы с написанием кода, который позволил бы напрямую получить информацию о пользователе и запросить информацию. Это моя структура MongoDB,

db.user.find();
user: 
    {
    "name" : "KSK", 
     "claim"  : [objectId("52ffc4a5d85242602e000000"),objectId("52ffc4a5d85242602e000001")] 
    }

claim: 

    [
       {
         "_id" : "52ffc4a5d85242602e000001",
         "claimName" :"XXXX"
       },
       {
         "_id" : "52ffc4a5d85242602e000000",
         "claimName" :"YYY"
       }
    ]

Мой класс Entity:

@Document(collection="user")
public  class User{
    @Id      
    private String id;
    private String name; 
    @DBRef
    private List<Claim> claim; 
    // setter and getter   
}

Класс претензии:

@Document(collection="Claim")
public class Claim{
    @Id 
    private String id; 
    private String claimName;   
}

У меня есть способ получить пользователей по именам, как показано ниже,

public User findByName(String name);

Если я попытаюсь использовать этот метод, я получаю сообщение об ошибке:

Не найдено преобразователя, способного преобразовать тип org.bson.types.ObjectId в тип java.lang.String

Итак, я изменил свой класс сущности User, как показано ниже,

Вместо private List<Claim> claim;

Поменял как Private List<ObjectId> claim;

Теперь, если я выполняю метод (findByName), я получаю объект пользователя, у которого есть оба заявленных идентификатора объекта ("52ffc4a5d85242602e000001","52ffc4a5d85242602e000000"), затем перебираю список утверждений и получаю детали утверждения, соответствующие идентификатору объекта утверждения.

Вместо этого, когда я выполняю findByName метод, я хочу получить сведения о пользователе и заявке. Как я могу добиться этой функциональности?


person KSK    schedule 30.05.2017    source источник
comment
Ваш первоначальный подход к List ‹Claim› выглядит неплохим. Вы уверены, что это не проблема верблюда? См. claimname в вашем классе Java и claimName в вашем JSON.   -  person Jan B.    schedule 30.05.2017
comment
@Matt, это просто опечатка. Я модифицировал сейчас.   -  person KSK    schedule 31.05.2017


Ответы (3)


Если вы ссылаетесь на свои Claims в классе User с помощью @DBRef, ваш JSON должен содержать не только идентификатор, но и ссылку на коллекцию, в которой также можно найти идентификатор, например:

{
  "name" : "KSK", 
  "claim" : [ 
     { 
       "$ref" : "claim", // the target collection
       "$id" : ObjectId("52ffc4a5d85242602e000000")
     }
  ] 
}

Вот как Spring-Data сопоставляет ваши объекты Java с MongoDB. Если вы начнете с пустой базы данных и позволите Spring создать и сохранить отношения, у вас не должно возникнуть проблем с использованием

 @DBRef List<Claim> claims;
person Jan B.    schedule 31.05.2017
comment
как я могу получить user_id заявки? - person Youssef Boudaya; 02.06.2021

Я предлагаю не выделять этот класс Claim в отдельный @Document или просто переключаться обратно на реляционные базы данных, потому что это не подход Mongo. Кроме того, если вы настаиваете на текущей архитектуре, вы можете попробовать использовать @DBRef выше этого List в User.class в что-то вроде этого:

public class ParentModel {

    @Id
    private String id;

    private String name;

    private ParentType parentType;

    private SubType subType;

    @DBRef
    private List<Model> models;

....
}
person Andrew Petryk    schedule 30.05.2017
comment
Я пропустил добавление DBRef в свой пост. Сейчас отредактировал. Пожалуйста, посмотрите сейчас. Как вы предположили, если я использую встроенные отношения, если встроенный документ продолжает слишком сильно увеличиваться в размерах, это может повлиять на производительность чтения / записи. Вот почему я решил обратиться к эталонным отношениям. - person KSK; 30.05.2017
comment
вы превысите 16 мб? Это должен быть огромный документ. Если вам удалось получить пользователя со списком ‹Claim›, я не совсем понимаю, что вы хотите над этим? Мб если вы объясните это более понятно, я постараюсь помочь - person Andrew Petryk; 30.05.2017
comment
Если я добавлю частный список DBRef ‹Claim›, я получаю сообщение об ошибке. Я упомянул об ошибке в своем посте. Что мне нужно, так это когда я вызываю findByName, тогда мне нужен пользователь, соответствующий деталям претензий. - person KSK; 30.05.2017
comment
вы сгенерировали геттеры и сеттеры? вы можете использовать Lombok для этой цели - person Andrew Petryk; 30.05.2017

в качестве альтернативы @DBRef взгляните на RelMongo (ссылка), который предоставляет мощный способ управлять отношениями, в вашем случае это будет так:

@OneToMany(fetch = FetchType.LAZY)
private list<Claim> claims;
person Chin    schedule 27.11.2019