Сопоставление объектов без потери существующих данных

Обычно сопоставители объектов предназначены для сценариев, чтобы сопоставить больший набор данных с небольшим набором (пример: Entity объект имеет много данных, но мы хотим вернуть только некоторые из них).

Сопоставители объектов обычно создают новый экземпляр целевого объекта небольшого набора и устанавливают необходимые поля из исходного объекта с большим набором, но у меня противоположный сценарий: у меня есть целевой объект, который уже содержит некоторые данные, и теперь мне нужно сопоставить новый источник объект с меньшим набором данных в целевой объект.

Исходный класс

public class SrcObj {
private String name;
private int i;

Класс назначения

public class DestObj {
    private String name;
    private int i;
    private float f;
    private boolean b;

DesObj уже содержит значение int i и float f, SrcObj имеет имя String и int, мне нужно сохранить данные SrcObj в DestObj без потери существующих данных.

Model Mapper всегда создает новый объект DestObj, который будет отображать в него SrcObj, но остальные поля пусты.

public class ObjectMapper {
public static void main(String[] args) {
    SrcObj src = new SrcObj("src name", 1);
    DestObj dest = new DestObj(null, 0, 1, true);
ModelMapper modelMapper = ObjectMapper.modelMapper();
    dest = modelMapper.map(src, DestObj.class);
    System.out.println(dest);
}

private static ModelMapper modelMapper() {
    ModelMapper modelMapper = new ModelMapper();
    PropertyMap<SrcObj, DestObj> orderMap = new PropertyMap<SrcObj, DestObj>() {
        protected void configure() {
            // map().setI(destination.getI());
            map().setI(source.getI());
            System.out.println("model mapper");
            map().setName(source.getName());
        }
    };

    modelMapper.addMappings(orderMap);
    return modelMapper;
}
}

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

как я могу иметь destObj, содержащий все значения destObj[name="src name", i=1,f=1.1,b=true]


person shrikant.sharma    schedule 30.06.2018    source источник
comment
Вы забыли задать вопрос....   -  person Joakim Danielson    schedule 30.06.2018
comment
modelmapper.org/javadoc /org/modelmapper/. Но по моему опыту, таких преобразователей следует избегать любой ценой: они экономят всего несколько строк тривиального кода для копирования свойств из одного объекта в другой, но значительно усложняют работу с более сложными сопоставлениями, неизменяемыми объектами и т. д. , И самое главное, они молча терпят неудачу, когда вы переименовываете свойство в исходном классе и не применяете тот же рефакторинг к целевому классу (или наоборот), что приводит к множеству ошибок, которые не случаются, если вы кодируете копию. самостоятельно.   -  person JB Nizet    schedule 30.06.2018
comment
@JBNizet Я уже просмотрел документацию, но безуспешно. да, я знаю последствия, но сейчас у меня есть простые объекты, так что это не имеет значения.   -  person shrikant.sharma    schedule 30.06.2018
comment
Затем опубликуйте полный минимальный пример того, что вы пробовали после использования метода, на который я ссылался, и точно расскажите, что вы ожидали, и что вместо этого произошло.   -  person JB Nizet    schedule 30.06.2018
comment
Привет @JBNizet Я надеюсь, что это то, что вы говорите modelMapper.map(src, dest);, но это дает ошибку времени компиляции Несоответствие типов: невозможно преобразовать из void в DestObj, потому что этот возвращаемый тип перегруженного метода имеет значение void.   -  person shrikant.sharma    schedule 30.06.2018
comment
Просто прочитайте сообщение об ошибке. Этот метод возвращает пустоту. Вы не можете назначить его результат dest. Да и незачем, так как этот метод не создает новый DestObj: он модифицирует dest. Так же, как вы не можете использовать dest = dest.setName("foo");. Вы просто используете dest.setName("foo");.   -  person JB Nizet    schedule 30.06.2018
comment
Я не хочу использовать геттеры или сеттеры, в этом весь смысл использования Object Mapper, в этом примере кажется только 1 геттер и сеттер, но в моем проекте их около 10-15.   -  person shrikant.sharma    schedule 30.06.2018


Ответы (2)


Во-первых, если вы не хотите использовать геттер/сеттер в своих классах, вы можете просто включить функцию сопоставления полей.

modelMapper.getConfiguration()
    .setFieldMatchingEnabled(true)
    .setFieldAccessLevel(AccessLevel.PRIVATE);

И вы можете просто modelMapper.map(src, dest) обновить свойства назначения из исходного кода.

person Chun Han Hsiao    schedule 01.07.2018

@Chun Han Hsiao спасибо за ваш ответ, это сработало, просто ради решения.

    SrcObj src = new SrcObj("src name", 1);
        DestObj dest = new DestObj(null, 0, 1, true);
    ModelMapper modelMapper = ObjectMapper.modelMapper();
 modelMapper.map(src, dest);
        System.out.println(dest);
person shrikant.sharma    schedule 01.07.2018