How do I tell Play Framework 2 and Ebean to save null fields?
Asked Answered
L

2

12

I'm using Play Framework 2 and Ebean. When a user submits a form to edit an existing object in the database, it doesn't save null values. I guess this is to prevent overwriting fields that aren't in the form with null. But how can I let them set fields in the form to null if they need to?

For example, the user edits an Event object. Event.date is 1/1/13. The user sets the Event.date field in the form to empty and submits the form. Inspecting Event.date in the debugger shows its value is null. I save the Event. If I look at the Event in the database, its value is still 1/1/13.

Edit: It seems there is a method for this. The only problem is it doesn't work on nested entities. Any solutions for this?

update(Object bean,Set<String> properties)
Landry answered 10/2, 2013 at 6:10 Comment(1)
(I'm the author of Ebean ORM) - Just a note that this question is old and against an old version of Ebean. Current behavior for "stateless updates" is that setting a null against a property should include that it the update - so just plain old update() should work as expected for properties set including null values.Danuloff
R
5

Create an ebean.properties file right next to the application.conf file and add this line to it:

ebean.defaultUpdateNullProperties=true
Ribera answered 7/11, 2013 at 12:9 Comment(0)
R
4

Null properties in Ebean are considered as unloaded, so to prevent accidental nulling properties that shouldn't be nulled, they are just excluded.

Because of this reverting Date (and other fields) to null in Ebean is... hard :). Last time when I had to do the same thing (revert Date) I used second query to do just... nulling the Date (after event.update(Object o)):

public static Result updateEvent(){
    Form<Event> eventForm = form(Event.class).bindFromRequest();

    // do some validation if required...

    Event event = eventForm.get();
    event.update(event.id);

    if (eventForm.get().date == null){
       Ebean
         .createUpdate(Event.class, "UPDATE event SET date=null where id=:id")
         .setParameter("id", page.id).execute();  
    }

}

On the other hand, if you are using comparison, for filtering events (always selecting newer than X), you can just set the date to very 'old' value, which also should do the trick. In this case you'll update the object only once.

private static final Date VERY_OLD_DATE = new GregorianCalendar(1, 0, 1).getTime();

public static Result updateEvent(){
    Form<Event> eventForm = form(Event.class).bindFromRequest();
    Event event = eventForm.get();
    if (eventForm.get().date == null){
        event.date = VERY_OLD_DATE;
    }

    event.update(event.id);
}

In this case in your HTML form you will need to clear the value of the form's field (or just send every time date like 0001-01-01), however it can be done easily even with JavaScript.

Resident answered 10/2, 2013 at 12:38 Comment(1)
The solution by Thunder seems to work for me, is there any reason adding ebean.properties isn't a good idea?Barajas

© 2022 - 2024 — McMap. All rights reserved.