Partial update of boolean fields Java REST

I want to ask if there is a way to solve the following problem in an elegant way.

I have a Java Rest application using JPA and Jersey. I want to be able to partially update my models.

I do it in one way (update) which will check the fields provided (! = Null) and update only the ones it works fine for all fields except boolean fields.

I would really appreciate if you can provide some ideas. I was thinking about Boolean type, but it doesn't seem very elegant.

Part of the resource:

...

@PUT
@Path("{id:[0-9][0-9]*}")
@Consumes(MediaType.APPLICATION_JSON)
public Response update((@PathParam("id") long id, Event event) {
    Event _event = dao.find(id);

    if (event.getTitle()!=null) _event.setTitle(event.getTitle());

    // in case variable finished is not provided we should not change anything 
    // if (event.getFinished()!=null) _event.setFinished(event.getFinished());

    dao.update(id, _event);
}

...

      

Model part:

@Entity
@XmlRootElement
public class Event implements Serializable {

    private String title;
    private boolean finished = false;

    public Event(){}    

    // getters, setters

    ...
}

      

The javascript part:

// Those ones work
Event.post({id:12, title:"Meet with Joe", finished:true}  // update all fields
Event.post({id:12, title:"Meet with Barack", finished:false} // update all fields
Event.post({id:12, finished:false} // partial update of boolean fields

// How to achieve this one without affecting other boolean fields? 
Event.post({id:12, title:"Meet with Joe"}
// We haven't provided "finished" value. We don't want to change it. 
// But system will update unprovided boolean field value with default.

      

+3


source to share


2 answers


I think I have found a solution. Instead of using the Event in Post argument, it's better to use JsonObject:



...

@PUT
@Path("{id:[0-9][0-9]*}")
@Consumes(MediaType.APPLICATION_JSON)
public Response update((@PathParam("id") long id, JSONObject json) {
    Event _event = dao.find(id);

    _event.setTitle(json.optString("title"));
    _event.setFinished(json.optBoolean("finished", _event.getFinished())); // if boolean value is not provided, we don't change it

    dao.update(id, _event);
}

...

      

0


source


Semantically, if you want to use your Event class to be able to express the concept of "partial event with some fields filled and some not" then having each field with a type that can be null makes sense, and IMO be an "elegant" solution ...

However, if that makes your event now have the ability to have zeros on what should be a non-empty field, simply because you want to use it in that update call as well - I guess that's the part you don't like about it. (i.e. you are essentially using the same event class as the model object that directly represents the database record, and this is a partial view of a portion of the event that only populates some fields)



Another approach might be to get a simple map from the client (ie instead of "event event" as the last parameter to update (), do "java.util.Map event") and just copy the values ​​it contains. If you need to do this, you can use reflection to make it easier to duplicate for multiple types of objects.

PS I don't have much experience with Jersey, so I'm not sure if it will work correctly with java.util.Map (which is an interface) as a param type or if it needs a specific class or maybe some other annotation (s). But I'm sure this concept can be made to work if you like the approach.

0


source







All Articles