Hi,

I have set up an application with MyFaces Orchestra. It seems to work fine,
except that no transaction is committed at the end of the conversation. I
tried both "access" and "manual" conversation scopes, both with the same
result. I'm probably missing something. Can someone assist me a little bit
here? Below are some snippets from the most important files in my project.

Best regards,
Bart Kummel

*applicationContext.xml:
*<?xml version="1.0" encoding="UTF-8"?>
  <beans ...>

    <!-- 1. initialization of all orchestra modules (required for core15
module) -->
    <import resource="classpath*:/META-INF/spring-orchestra-init.xml" />

    <!-- 2. the conversation scopes -->
    <bean
class="org.springframework.beans.factory.config.CustomScopeConfigurer">
      <property name="scopes">
        <map>
          <entry key="conversation.manual">
            <bean
class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
              <property name="timeout" value="30" />
              <property name="advices">
                <list>
                  <ref bean="persistentContextConversationInterceptor"/>
                </list>
              </property>
            </bean>
          </entry>

          <entry key="conversation.access">
            <bean
class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
              <property name="timeout" value="30" />
              <property name="advices">
                <list>
                  <ref bean="persistentContextConversationInterceptor"/>
                </list>
              </property>
              <property name="lifetime" value="access"/>
            </bean>
          </entry>
        </map>
      </property>
    </bean>

    <!-- 3. the "entity manager" manager -->
    <bean id="persistentContextConversationInterceptor"

class="org.apache.myfaces.orchestra.conversation.spring.PersistenceContextConversationInterceptor">
      <property name="persistenceContextFactory"
ref="persistentContextFactory"/>
    </bean>

    <!-- 4. conversation - persistence adapter -->
    <bean id="persistentContextFactory"

class="org.apache.myfaces.orchestra.conversation.spring.JpaPersistenceContextFactory">
      <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!-- 5. persistence -->
    <bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

    <tx:annotation-driven />

    <bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
      <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
      <property name="persistenceUnitName" value="MIAS-EJB"/>
    </bean>

    <bean name="editKidController"
          class="inc.monsters.mias.controller.EditKidController"
          scope="conversation.manual"
          autowire="byName"/>
    <bean name="editKidForm"
          class="inc.monsters.mias.backing.EditKidForm"
          scope="request"
          autowire="byName"/>
    <bean name="editScaredForm"
          class="inc.monsters.mias.backing.EditScaredForm"
          scope="request"
          autowire="byName"/>
    <bean name="kidsTable"
          class="inc.monsters.mias.backing.KidsTable"
          scope="request"
          autowire="byName"/>

    <!-- Enable injection for @EJB annotations -->
    <context:component-scan base-package="inc.monsters.mias" />

  </beans>*

EditKidController.java:
*package inc.monsters.mias.controller;

public class EditKidController {
    @EJB(mappedName="mias/KidService")
    private KidService service;
    private Kid selectedKid;

    public Kid getSelectedKid() {
        if(null == selectedKid) {
            FacesContext context = FacesContext.getCurrentInstance();
            selectedKid =
(Kid)context.getExternalContext().getRequestMap().get("selectedKid");
        }
        return selectedKid;
    }

    public void setSelectedKid(Kid selectedKid) {
        this.selectedKid = selectedKid;
    }

    @Transactional
    public void saveSelected(ActionEvent event) {
        Kid k = getSelectedKid();
        log.fine("Saving kid " + k.getId() + ": " + k.getFirstName() + " " +
k.getLastName() + ".");
        if(service.existsKid(k)) {
            service.updateKid(k);
        } else {
            service.addKid(k);
        }
    }

    @Transactional
    public void updateScareData(ActionEvent event) {
        Kid k = getSelectedKid();
        k.getEmployee().setKidsScared(k.getEmployee().getKidsScared() + 1);
    }

    public void endConversationAndSave(ActionEvent event) {
        saveSelected(event);
        endConversation(event);
    }

    public void endConversation(ActionEvent event) {
        Conversation.getCurrentInstance().invalidate();
    }
}

*EditKidForm.java:*
package inc.monsters.mias.backing;

@ViewController(viewIds={"EditKid.xhtml"})
public class EditKidForm {
    private EditKidController editKidController;

    public EditKidController getEditKidController() {
        return editKidController;
    }

    public void setEditKidController(EditKidController controller) {
        this.editKidController = controller;
    }
}

*EditKid.xhtml:*
<?xml version="1.0" encoding="UTF-8" ?>
<tr:document ...>

<ui:composition template="templates/template.xhtml">
  <ui:define name="title">Edit kid</ui:define>
  <ui:define name="content">
    <tr:panelFormLayout>
      ...
        <f:facet name="footer">
          <tr:panelButtonBar halign="right">
            <tr:commandButton text="#{msg.apply}" id="btnApply"
partialSubmit="false" action="apply"

actionListener="#{editKidForm.editKidController.saveSelected}"/>
            <tr:commandButton text="#{msg.ok}" action="ok"

actionListener="#{editKidForm.editKidController.endConversationAndSave}" />
            <tr:commandButton text="#{msg.cancel}" action="cancel"
immediate="true"

actionListener="#{editKidForm.editKidController.endConversation}" />
          </tr:panelButtonBar>
        </f:facet>
      </tr:panelFormLayout>
  </ui:define>
</ui:composition>*

*The EditKid.xhtml page is called from the *Kids.xhtml* page:
<?xml version="1.0" encoding="UTF-8" ?>
<tr:document ...>

<ui:composition template="templates/template.xhtml">
  <ui:define name="title">Overview of kids!</ui:define>
  <ui:define name="content">
      <tr:table var="kid" value="#{kidsTable.kids}" rows="20" id="kids"
                rowBandingInterval="1" horizontalGridVisible="false"
                allDetailsEnabled="true" rowSelection="multiple"
                binding="#{kidsTable.table}"
                selectionListener="#{kidsTable.selectionChanged}"
                autoSubmit="true" partialSubmit="true" >
        <mias:column ... />
        ...
        <mias:column columnName="edit" headerName="emptyTableHeader"
custom="true">
          <tr:commandLink action="edit" immediate="true">
            <tr:image source="../images/pencil.png"
inlineStyle="border-width: 0px;" />
            <tr:setActionListener to="#{requestScope.selectedKid}"
from="#{kid}"/>
          </tr:commandLink>
        </mias:column>
     </tr:table>
  </ui:define>
</ui:composition>

</tr:document>

Reply via email to