Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

I ran into a use case recently that required the existing conversation to end and a new one to begin when the user selects a new value from a h:selectOneMenu component.

The use case is described as follows. User selects a primary key value from a drop-down which causes a dataTable to be populated. There is already another dataTable populated. User clicks on checkboxes for each row in each dataTable to assign/remove rows from each dataTable. One of the business requirements is if the user selects a different primary key value at bet365 after one has already been selected and the long-running conversation has not already ended by clicking submit or cancel (or timed out) , clear out all the data and refresh the screen. This basically means end the current conversation and begin a new one when the user selects a different value from in the drop-down.

In order to handle this scenario in the same SFSB backing method, you must use the Seam Conversation API. This API is not covered at all in the Seam ref doc or Seam in Action book. Refer to the following URL for API info: http://www.redhat.com/docs/manuals/jboss/jboss-eap-4.3/doc/seam/api/org/jboss/seam/core/Conversation.html

Here is some of the code that implements this use case:

.xhtml:

<h:form id="locationform">  			
      <h:panelGrid columns="4">
			<h:panelGrid styleClass="shimsLabel">
				<h:outputText          value="Select Location"/>
			    </h:panelGrid>
			   
			    <h:selectOneMenu 		id="sellocation"	value="#{techDeployToUser.selectedLocation}">
					<f:selectItems 		id="locationList" 	value="#{techDeployToUser.hardwareLocations}" /> 
			    <a4j:support 		event="onchange" 	ajaxSingle="true" action="#{techDeployToUser.populateUser}" reRender="selectedUser, richMessages, userQueueTable, techQueueTable, firstNameLastName"/>
			</h:selectOneMenu>	
			<h:panelGrid styleClass="shimsLabel">
				<h:outputText          value="User"/>
			</h:panelGrid>
			<h:outputText          id = "selectedUser" value="#{techDeployToUser.selectedUser}"/>			        
		    </h:panelGrid>
		</h:form>	

SFSB:

public void populateUser() {
		
		Conversation conversation = Conversation.instance();
		
		if (conversation != null) {
			log.info("in setSelectedLocation(): Conversation.instance().isLongRunning() = "+conversation.isLongRunning());
			log.info("in setSelectedLocation(): Conversation.instance().getDescription() = "+conversation.getDescription());
			log.info("in setSelectedLocation(): Conversation.instance().getId() = "+conversation.getId());
			log.info("in setSelectedLocation(): Conversation.instance().getParentId() = "+conversation.getParentId());
			log.info("in setSelectedLocation(): Conversation.instance().getRootId() = "+conversation.getRootId());
			log.info("in setSelectedLocation(): Conversation.instance().getTimeout() = "+conversation.getTimeout());			
			
			conversation.end(true);
		}
		else {
			log.info("in setSelectedLocation(): there is no active conversation");
		}
		conversation.begin();
		conversation.changeFlushMode(FlushModeType.MANUAL);
		
		String locationNo = getSelectedLocation();
		List<UTbUser> selectedUserList = entityManager.createQuery("SELECT user "+
															"FROM UTbUser user, "+
															"TbLocation location "+
															"WHERE user.userId = location.userId AND " +
															"location.locationNo = :locationNo")
															.setParameter("locationNo", locationNo)
															.getResultList();
		if(selectedUserList != null && selectedUserList.size() > 0) {
			String fname = ((UTbUser)selectedUserList.get(0)).getFirstName();
			String lname = ((UTbUser)selectedUserList.get(0)).getLastName();
			selectedUser = fname + " " + lname;
		}
		else {
			facesMessages.add("No equipment or user assigned to location "+locationNo);
			selectedUser = "";
		}
		
		//set @Factory List to null to force Seam to re-populate with fresh data...
		userLocEquipList = null;
	}

In this example, using

Conversation.instance().end(true)
is the equivalent of using
@End(beforeRedirect=true)
so the conversation will be destroyed prior to redirect. We are also using SMPC so that's why you see
conversation.changeFlushMode(FlushModeType.MANUAL)
The
entityManager.flush()
is called in the submit() method.