2

When a JSF form field is wired into an entity bean field (which is mapped to a DB field), each setter in the entity bean is called regardless of whether the user changed the form field value in the front end, i.e. the setters on unchanged fields are invoked the same as those that have changed but their new value is the same as the old value.

My question is simple: Is there a way to configure JSF to only call the setters mapped to the fields that have changed in the front end? The reason for this is that I have a requirement by which I have to detect deltas on every persist and log them, more about which can be read in this question.

Community
  • 1
  • 1
amphibient
  • 29,770
  • 54
  • 146
  • 240
  • What if jsf did that? How would you detect that the field did (not) change and log that? I searched the internet/stackoverflow for several solutions and found some links related to your other post. So I think that other post is still way more relevant than this question – Kukeltje Feb 25 '15 at 22:34
  • if JSF did that, I could modify each setter to add that field to the set of changed fields without having an if checking if the new val is different than the old. – amphibient Feb 25 '15 at 22:36
  • of course, an elegant solution to the other question that eliminates the need to individual field checks would be preferable. this is just Plan B – amphibient Feb 25 '15 at 22:39
  • Adding it to a set of changed fields or detecting a change to is a small difference if you create a base entity and do all the work in there. It is just adding one call in the setter. Personally I'd approach it differently, but will reply in your other post – Kukeltje Feb 25 '15 at 22:40

1 Answers1

3

Maybe I didn't understand you clearly, but why are you mapping directly your entity beans to a JSF view ?! IMHO it would be better if you add managed beans between your JSF pages and the entities in order to better separate your business logic from data access.

Any way, I think the easiest solution to impelement for that case is by making use of Value Change Events which are invoked "normally" after the Process Validations phase (unless you make use of the immediate attribute).

The good news about Value Change Events (regarding your example) is they are invoked ONLY after you force form submit using JavaScript or Command components AND the new value is different from the old value.

So, as an example on how to use value change listeners, you can add valueChangeListner attribute to each of your JSF tags like following:

<h:inputText id="input" value="#{someBean.someValue}" 
   valueChangeListener="#{someBean.valueChanged} />

Then, implement your valueChanged() method to look something like:

public void valueChanged(ValueChangeEvent event) {         

   // You can use event.getOldValue() and event.getNewValue() to get the old or the new value

}

Using the above implementation, may help you to separate your logging code (it will be included in the listeners) from your managed properties setters.

NB: Value Change Listeners may also be implemetend otherwise using the f:valueChangeListener Tag, but this is not the best choice for your example (you can find some examples in the section below, just in case)

See also:

Community
  • 1
  • 1
Tarik
  • 4,961
  • 3
  • 36
  • 67
  • it is an iterative form, meaning it contains as many iterations of the same form as there are rows in the DB that correspond to the view. The managed bean returns an array of the entity so each form iteration is mapped to that. your answer assumes it is a singular form and it isn't. imagine if the form represents all your children and you can have 0-X children, if you have 3, there will be a data grid of 3 forms, each of which looks the same except for the values within. so each field in each form is mapped to `entity.someField` – amphibient Feb 26 '15 at 02:52
  • @amphibient Then, if your logging code is the same you will only use one single listener method in your managed bean e.g `public void valueChanged(ValueChangeEvent event)` and in your input fields you just need to add the attribute `valueChangeListener="#{yourManagedBean.valueChanged}` no matter how many forms you have, it's just an attribute that will be added in each input you want to track. Hope, I understand what you mean, if you saw that I am so far from what you are looking for, please provide some code so that I will better understand what I misunderstood :) – Tarik Feb 26 '15 at 03:57
  • 1
    That `if` statement is unnecessary (as stated in your 3rd paragraph). – BalusC Feb 28 '15 at 12:54
  • @BalusC Ops!! I said that the listener will not execute unless the old value and the new value are different and then I added that uncessary statement! Thanks for your notice :) I updated – Tarik Feb 28 '15 at 13:58