Stream API Java удаление поля
Не могу понять как убрать поле из объекта. Есть два класса:
public class PatientSubCategory {
private String id;
private String code;
private String description;
private PatientCategory category;
}
public class PatientCategoryDTO {
private String id;
private String code;
private String description;
private List<PatientSubCategory> subCategories;
}
Мне нужно удалить поле PatientCategory category; из элементов объекта List<PatientSubCategory> subCategories;
Делаю я это следующим образом, но это не совсем то, что мне нужно:
public PatientCategoryDTO(PatientCategory patientCategory)
{
ArrayList<PatientSubCategory> localSubCategories = new ArrayList<PatientSubCategory>();
this.id = patientCategory.getId();
this.code = patientCategory.getCode();
this.description = patientCategory.getDescription();
if (patientCategory.getSubCategories() != null)
{
for (PatientSubCategory patientSubCategory: patientCategory.getSubCategories())
{
patientSubCategory.setCategory(null);
localSubCategories.add(patientSubCategory);
}
this.subCategories = localSubCategories;
}
}
Получаю такой вывод:
[
{
"id": "1",
"code": "1",
"description": "Работники ОАО",
"subCategories": [
{
"id": "1||1",
"code": "1",
"description": " Работники группы машинистов, водителей и их помощников",
"category": null
},
{
"id": "1||3",
"code": "3",
"description": " Работники станционно-маневровой группы",
"category": null
},
{
"id": "1||4",
"code": "4",
"description": " Работники группы, обслуживающей поезда в пути следования",
"category": null
}
]
},
{
"id": "2",
"code": "2",
"description": "Пенсионеры",
"subCategories": []
}
]
А нужно, чтобы поле "category": null вообще не было.
Подскажите, пожалуйста, как это сделать?
Ответы (1 шт):
Проще/правильнее было бы использовать корректный DTO объект для подкатегорий, не содержащий ссылки на родительскую категорию.
Возможное решение:
- добавляется DTO-класс
PatientSubCategoryDTOбез ссылки на родительскую категорию, с конструктором, принимающим сущность-подкатегориюPatientSubCategory
@Data
@AllArgsConstructor
public class PatientSubCategoryDTO {
private String id;
private String code;
private String description;
public PatientSubCategoryDTO(PatientSubCategory subcategory) {
this(subcategory.getId(), subcategory.getCode(), subcategory.getDescription());
}
}
- тип элементов списка в
PatientCategoryDTOменяется на новый DTO-класс - переписывается конструктор в DTO-классе
PatientCategoryDTO, чтобы правильно преобразоватьList<PatientSubCategory>вList<PatientSubCategoryDTO>
@Data
@AllArgsConstructor
public class PatientCategoryDTO {
private String id;
private String code;
private String description;
private List<PatientSubCategoryDTO> subCategories;
public PatientCategoryDTO(PatientCategory category) {
this(category.getId(), category.getCode(), category.getDescription(),
Optional.ofNullable(category.getSubcategories())
.map(subs -> subs.stream().map(PatientSubCategoryDTO::new).toList())
.orElse(null)
);
}
}
Таким образом, не будут смешиваться классы DTO и соответствующих сущностей, и не возникнет необходимости устанавливать в null поле в сущности PatientSubCategory.
Другие варианты решения, без создания отдельного DTO класса, могут опираться на использование стандартных Jackson аннотаций для управления сериализацией полей:
- Использовать
@JsonBackReferenceдля поля-ссылки на родительскую категорию и@JsonManagedReferenceдля коллекции подкатегорий:
public class PatientSubCategory {
private String id;
private String code;
private String description;
@JsonBackReference
private PatientCategory category;
}
public class PatientCategoryDTO {
private String id;
private String code;
private String description;
@JsonManagedReference
private List<PatientSubCategory> subCategories;
}
Это в частности позволит избежать рекурсивной зависимости и StackOverflowError при сериализации.
- Использовать
@JsonIgnoreдля поля-ссылки на родительскую категорию:
public class PatientSubCategory {
private String id;
private String code;
private String description;
@JsonIgnore
private PatientCategory category;
}
Простой запрет сериализации указанного поля.
- Использовать
@JsonIgnorePropertiesдля поля-ссылки на родительскую категорию на уровне класса, аналог@JsonIgnore:
@JsonIgnoreProperies(value = {"category"})
public class PatientSubCategory {
private String id;
private String code;
private String description;
private PatientCategory category;
}
Такие варианты позволят "сэкономить" на создании новых DTO-объектов, благодаря переиспользованию сущности PatientSubCategory, но такой подход немного грязный по сравнению с предыдущим.