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>