ここで作業しているセットアップは、Seam-2.3 を使用した JBoss AS7 の JSF2 です。
私は、大きなテンプレートで次の<a4j:commandButton>
ように呼び出されるマネージャー Bean を持っています。
<rich:dataTable value="#{listFactory.getMyList()}" var="ll">
...
</rich:dataTable>
...
<a4j:repeat id="jobs" value="#{person.jobs}" var="job">
<h:outputText value="#{job.name}" />
</a4j:repeat>
<a4j:commandButton value="more" immediate="true"
action="#{personManager.addJob}" render="jobs" limitRender="true" />
からの対応するコードpersonManager
:
@Name("personManager")
@Scope(ScopeType.CONVERSATION)
public class PersonMgr {
private Person person;
@Begin(flushMode = FlushModeType.MANUAL)
public void selectObjects() {
// grab the person from the request if there's one
}
@End
public void saveChanges() {
em.flush();
}
public void addJob() {
person.getJobs().add(new Job());
}
}
ここで行うことは、プライベートでまだ一時的なエンティティ BeanpersonManager
を呼び出すことです。それができる前に、リクエストは次のスタックトレースで終了します:person.jobs.add(new Job())
person
javax.el.ELException: /person.xhtml @412,95 value="#{listFactory.getMyList()}": org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Person
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114) [jsf-impl-2.1.7-jbossorg-2.jar:]
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at org.richfaces.component.UISequence.getValue(UISequence.java:175) [richfaces-components-ui.jar:4.3.0.Final]
at org.richfaces.component.UISequence.createExtendedDataModel(UISequence.java:109) [richfaces-components-ui.jar:4.3.0.Final]
at org.richfaces.component.UIDataTableBase.createExtendedDataModel(UIDataTableBase.java:252) [richfaces-components-ui.jar:4.3.0.Final]
at org.richfaces.component.UIDataAdaptor.getExtendedDataModel(UIDataAdaptor.java:459) [richfaces-components-ui.jar:4.3.0.Final]
at org.richfaces.component.UIDataAdaptor.setRowKey(UIDataAdaptor.java:272) [richfaces-components-ui.jar:4.3.0.Final]
at org.richfaces.component.UIDataAdaptor.visitTree(UIDataAdaptor.java:1312) [richfaces-components-ui.jar:4.3.0.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIForm.visitTree(UIForm.java:371) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at org.richfaces.context.ExtendedPartialViewContextImpl.visitActivatorComponent(ExtendedPartialViewContextImpl.java:448) [richfaces-core-impl.jar:4.3.0.Final]
at org.richfaces.context.ExtendedPartialViewContextImpl.visitActivatorAtExecute(ExtendedPartialViewContextImpl.java:309) [richfaces-core-impl.jar:4.3.0.Final]
at org.richfaces.context.ExtendedPartialViewContextImpl.getExecuteIds(ExtendedPartialViewContextImpl.java:98) [richfaces-core-impl.jar:4.3.0.Final]
at org.richfaces.context.ExtendedPartialViewContextImpl.isExecuteAll(ExtendedPartialViewContextImpl.java:148) [richfaces-core-impl.jar:4.3.0.Final]
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:929) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.7-jbossorg-2.jar:]
これをデバッグすると、ExtendedPartialViewContext は実際に、commandButton コンポーネントのみを実行することになっていることを「取得」しますが、完全な JSF ツリーのレンダリングウォークに進むように見えますか? つまり、なぜそのリストの値が評価されるのでしょうか? rendered=false
ポストバック時に評価する必要があるdivにもあります。ここで明らかに明らかな何かが欠けているに違いありませんか?
私が最初に思いついたのは、pages.xml が干渉している (呼び出しselectObjects
だが、アクションに属性がon-postback="false"
設定されている) か、追加する必要が<a4j:keepAlive>
あるということです。 AJAX リクエストも?