Шаблон Spring Data MongoDB конвертируется в неправильный класс - PullRequest
0 голосов
/ 16 мая 2018

При использовании Spring 5.0.6 и Spring-Data-Mongo 2.0.7 у меня возникает проблема при извлечении сущностей, преобразованных в неправильный класс.См. Следующий упрощенный сценарий:

Настройка сущности:

public class PersistableObject {
  @Id @Field("_id") private String id; 
}

@Document(collection = "myapp_user")
public class User extends PersistableObject {...}

public class RealUser extends User {...}

public class VirtualUser extends User {...}

Итак, существует общая коллекция MongoDB , в которой хранятся оба типа User, различаемые автоматическидобавлено свойство _class .

Кроме того, существует репозиторий, в который вставляется шаблон MongoTemplate.

@Autowired 
private org.springframework.data.mongodb.core.MongoTemplate template;

Пока все хорошо.Теперь, если я хочу получить все документы, содержащие RealUser, я мог бы назвать это

template.findAll(RealUser.class)

Я бы ожидал, что шаблон найдет все документы, имеющие свойство дискриминатора _class установите com.myapp.domain.RealUser.

Но это не работает, как ожидалось.Я даже получаю все VirtualUser s, а также помещаю их в объекты типа RealUser, при этом все свойства, относящиеся к VirtualUser, отсутствуют, а все свойства, относящиеся к RealUser, установлены на null.

Кроме того, когда я иду и сохраняю User, который на самом деле является VirtualUser в MongoDB, но был сжат в класс RealUser, Spring изменит свойство _class нанеправильный тип, магически , преобразующий VirtualUser в RealUser.

Таким образом, оба метода здесь будут загружать всю коллекцию и сжимать все объекты в указанный класс, даже если он неправильный:

 template.findAll(VirtualUser.class)
 template.findAll(RealUser.class)

Такое поведение, вероятно, нежелательно, или еслизначит, это крайне обманчиво и вредно.Вы можете легко уничтожить все данные с помощью этого.

Может кто-нибудь пролить свет на это?

1 Ответ

0 голосов
/ 17 мая 2018

Я создал билет в Spring's Jira. Найти комментарий Оливера ниже:

Метод на самом деле работает, как и ожидалось, но я согласен, что нам нужно улучшить JavaDoc. Метод в основном указан как «Загрузить документы данного типа настроены на сохранение и сопоставление всех их (отсюда и название) к данному типу ". Тип, данный ему не используется в качестве критерия сопоставления типов одновременно. Каждое ограничение Вы хотите подать заявление на документы должны быть применены через экземпляр Query, который предоставляет метод… .restrict (…), который позволяет выбирать только документы, содержащие информацию о типе.

Причина, по которой findAll работает так, как она работает, заключается в том, что обычно говоря - т.е. без сценария наследования - нам нужно иметь возможность читать все документы, даже если они не имеют какого-либо типа Информация. Примите коллекцию с документами, представляющими людей которые не были написаны с использованием Spring Data. Если findAll (Person.class) применяет ограничения типа, вызов вернет нет документов, даже если там были документы. К сожалению мы не знаю, если коллекция собирается запрашивать носит тип Информация. На самом деле, некоторые документы могут содержать информацию о типе, некоторые не могут. Единственный способ разумно контролировать это, это позволить пользователь решает, что он может либо вызвать Query.restrict (…), либо нет. Первый выбирает документы только с информацией о типе, последний.

Как я уже сказал, я полностью понимаю, что JavaDoc может вводить в заблуждение здесь. Я собираюсь использовать этот билет, чтобы улучшить это. Хотел бы услышать, если использование Query.restict (…) позволяет вам достичь того, чего вы хотите.

...