3

I want to do a partial update on one of my entities but if one propertie is null then the entity to be updated gets that value set to null too. I want that if a property from the source is null then to keep the one from the source.

I have tried this but no luck:

    @Bean
    public ModelMapper modelMapper() {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration().setPropertyCondition(Conditions.isNotNull());
        modelMapper.createTypeMap(String.class, Date.class);
        modelMapper.addConverter(new StringToDate());
        modelMapper.addConverter(new DateToString());
        return modelMapper;
    }

Then I update my object like this:

    @Override
    public void editUser(final User user) {
        UserDocument userDocument = this.usersRepository.findByIdAndActivo(user.getId(), true)
                .orElseThrow(UserNotFoundException::new);

        userDocument = this.modelMapper.map(user, UserDocument.class);
        this.usersRepository.save(userDocument);
    }

The user object has 1 property set at null while the object userDocument has it with a value, then when I save it in the database that value is gone (because it has transformed into null).

What can be wrong?

Thanks.

Wrong
  • 1,195
  • 2
  • 14
  • 38
  • 1
    setting userDocument = assigns it to a reference to the output of ModelMapper.map, and thus loses any information that were in it previously (when it referred to a different location). If you want to preserve things and copy the nonnull, you need to create a method of USerDocument that takes another UserDocument as a parameter and does the updating to "this" for the non-null fields of the parameter – Jeremy Kahan May 29 '19 at 12:01
  • what's the purpose of this configuration then? modelMapper.getConfiguration().setPropertyCondition(Conditions.isNotNull()) @JeremyKahan – Wrong May 29 '19 at 12:03
  • 1
    that is a fair question, and I am not sure. Oh, I see you figured it out. It helps with merging but not creating something fresh. – Jeremy Kahan May 29 '19 at 12:21

3 Answers3

6

Okay so that configuration isn't for the purpose I thought it was.

I've solved the issue by merging the updated object with the old one like this:

    @Override
    public void editUser(final User user) {
        UserDocument userDocument = this.usersRepository.findByIdAndActivo(user.getId(), true)
                .orElseThrow(UserNotFoundException::new);

        this.modelMapper.map(user, userDocument);
        this.usersRepository.save(userDocument);
    }
Wrong
  • 1,195
  • 2
  • 14
  • 38
4

You can solve in this way:

@Configuration
public class ModelMapperConfig {

    @Bean
    public ModelMapper modelMapper() {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration().setSkipNullEnabled(true);

        return modelMapper;
    }
}
Felipe Pereira
  • 1,368
  • 16
  • 26
-3

Mybatis framework? You have not set selective save --selective

<insert id="insertSelective" parameterType="com.zjl.domain"> insert into table_name <trim prefix="(" suffix=")" suffixOverrides=","> <if test="id != null"> id, </if> <if test="createDate != null"> create_date, </if> <if test="modifiedDate != null"> modified_date, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="id != null"> #{id,jdbcType=BIGINT}, </if> <if test="createDate != null"> #{createDate,jdbcType=TIMESTAMP}, </if> <if test="modifiedDate != null"> #{modifiedDate,jdbcType=TIMESTAMP}, </if> </trim> </insert>

  • No, it's MongoDB. I don't think that is the issue anyways. It should use the destination's fields when the source's ones are null – Wrong May 29 '19 at 11:55