0

ここで作業しているセットアップは、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 リクエストも?

4

1 に答える 1

0

render=false の場合でも、UIDataAdaptor を拡張するコンポーネントの value 属性が「ツリーへのアクセス」で評価されるという RichFaces のバグがあります: https://issues.jboss.org/browse/RF-11382

バグが修正された RichFaces 4.3.0.Final に更新してみるか、回避策を適用してください (UIDataAdaptor を拡張するすべてのコンポーネントで回避策を繰り返す必要があります)。

public class UIDataTableWorkaround extends UIDataTable {
  @Override
  public void setRowKey(FacesContext facesContext, Object rowKey) {
    if (rowKey == null && getRowKey() == null) {
      return;
    }
    super.setRowKey(facesContext, rowKey);
  }
}

そしてfaces-configで:

  <component>
    <component-type>org.richfaces.DataTable</component-type>
    <component-class>com.example.UIDataTableWorkaround</component-class>
  </component>
于 2013-02-28T19:45:16.743 に答える