Olek
Olek

Reputation: 359

Coping fields between two objects (entities)

I have fallowing code:

public Osoba updateOsoba(String input) throws Exception {

    class FieldCopier {          // in progress....
        void updateField() {
        }
    }

    Osoba in = null;
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    in = mapper.readValue(input, Osoba.class);

    final int osobaId = Optional
            .ofNullable(in.getOsobaId())
            .orElseThrow(() -> new Exception("....."));

    Osoba os = osobaDao.findOne(osobaId);
    if (in.getOsobaImiona() != null) os.setOsobaImiona(in.getOsobaImiona());            
    if (in.getOsobaNazwisko() != null) os.setOsobaNazwisko(in.getOsobaNazwisko());
    //....

    return in;
}

This construction in my opinion is susceptible for mistakes:

if (in.getOsobaImiona() != null) os.setOsobaImiona(in.getOsobaImiona());

I have an idea to create a function that makes this change more simple, so I created inner class FieldCopier with method updateField(). I want to do something like that:

FieldCopier fc = new FieldCopier();
fc.updateField(in::getOsobaImiona, os::setOsobaImiona)

instead:

if (in.getOsobaImiona() != null) os.setOsobaImiona(in.getOsobaImiona()); 

But I have no idea how to implement method updateField(), I want to use reference to function but I don't know how. Is it possible to do it in that way? Or maybe there is a better way to do that?

Upvotes: 1

Views: 59

Answers (2)

Guilherme Alencar
Guilherme Alencar

Reputation: 1403

The possible thing you can do is:

public void updateField (Object objectToUpdate, String functionName, Object newValue) {
    try {
        Method method = objectToUpdate.getClass().getMethod(functionName, String.class);
        method.invoke(objectToUpdate, newValue);
    }catch (Exception e){
        e.printStackTrace();
    }
}

and call it as follows:

updateField(os, "setOsobaImiona", in.getOsobaImiona());

The method.invoke() will call the function os.setOsobaImiona(in.getOsobaImiona()). I am considering the parameter is an string, otherwise you should change the second parameter of getMethod() call.

Upvotes: 1

Adina Rolea
Adina Rolea

Reputation: 2109

You can use the updater feature from jackson.

//set this to not update a non null value with null
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

//find your source object for updating 
Osoba source = osobaDao.findOne(osobaId);

// update fields based on input json
source = objectMapper.readerForUpdating(source)
            .readValue(input);

Where input contains a json mapped to Osaba object.

Upvotes: 1

Related Questions