BalusC opened a new pull request, #1130:
URL: https://github.com/apache/myfaces/pull/1130
This PR targets `4.1.x`. The same change is needed on `main`, which has the
same commit (3ca891be2). Please upmerge or cherry-pick it into `main`
yourselves.
## Problem
Since 4.1.4, an input can keep rendering a stale local value forever, while
a readonly input bound to the same property follows the model. Reproducer:
```xml
<h:form id="form">
<h:selectOneMenu id="rendered" value="#{bean.rendered}">
<f:selectItem itemValue="#{false}" itemLabel="Hide" />
<f:selectItem itemValue="#{true}" itemLabel="Show" />
<f:ajax execute="@form" render="@form" />
</h:selectOneMenu>
<h:panelGroup id="group" rendered="#{bean.rendered}">
<h:commandButton id="increment" value="Increment"
action="#{bean.increment}">
<f:ajax execute="@this" render="@form" />
</h:commandButton>
<h:inputText id="editable" value="#{bean.value}" />
<h:inputText id="readonly" value="#{bean.value}" readonly="true" />
</h:panelGroup>
</h:form>
```
```java
@Named @ViewScoped
public class Bean implements Serializable {
private boolean rendered;
private int value;
public void increment() {
value++;
}
// Getters and setters.
}
```
Select "Show", click "Increment" twice, select "Hide" and then "Show" again,
and click "Increment" twice. The value of each input after each step, editable
first:
| Step | MyFaces 4.1.4 | MyFaces 4.1.3 |
|---|---|---|
| Show | 0, 0 | 0, 0 |
| Increment | 1, 1 | 1, 1 |
| Increment | 2, 2 | 2, 2 |
| Hide, then Show | 2, 2 | 2, 2 |
| Increment | **2**, 3 | 3, 3 |
| Increment | **2**, 4 | 4, 4 |
MyFaces 4.1.4 gives the same result with server and with client side state
saving.
## Cause
The "Hide" request executes `@form` while the group is still rendered, so
the editable input gets a local value. During Update Model Values the menu sets
`rendered` to `false` before the walk reaches the group, so the input never
reaches `updateModel()`, which would clear the local value. The local value is
saved in the `StateHelper`, but since 3ca891be2 on `main` and 4e2bf732f on
`4.1.x` ("[perf] use and optimize TransientStateHelper, …") `valid` and
`localValueSet` are held in the `TransientStateHelper`, and that is not saved
during Render Response. On every later request, `updateModel()` stops at
`!isLocalValueSet()`, never clears the local value, and `getValue()` keeps
returning it before it evaluates the value expression.
## Change
`isValid()`, `setValid()`, `isLocalValueSet()` and `setLocalValueSet()` use
the `StateHelper` again, with the same bodies as in 4.1.3, and `localValueSet`
and `valid` are back in `INITIAL_STATE_PROPERTIES`. A default value is still
not written when the component has no entry for it yet, so an input at its
defaults adds nothing to the saved state.
`submittedValue` stays in the `TransientStateHelper`. It is per-request
state. 4.1.3 did save it, so this is the one difference to 4.1.3 which remains.
Two comments in `EditableValueHolderState` described `valid` and
`localValueSet` as transient state, and are updated accordingly.
This gives back part of the speed gain of the perf commit: setting `valid`
or `localValueSet` is a `StateHelper` put again, also per row of a `UIData` or
`UIRepeat`. The saved state does not grow from it, because a value which is
back at its default is removed from the delta before saving.
The new `UIInputPSSTest` saves and restores the state during Render
Response, as for the view state, because outside that phase
`UIComponentBase.saveState()` also saves the transient state. Without the
change in `UIInput`, two of its tests fail. Without the re-added
`INITIAL_STATE_PROPERTIES` entries, two of its tests fail as well. The full
`api` and `impl` builds pass.
Mojarra made the same change in 4.0.19 and 4.1.10, got the same report in
eclipse-ee4j/mojarra#6019, and fixed it the same way in
eclipse-ee4j/mojarra#6021.
🤖 Generated with Claude Opus 5.5
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]