Help

Controls

PermLinkWikiLink

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.

Forum: Seam Users Forum ListTopic List
03. Oct 2008, 12:26 CET | Link

Hi,

I am experiencing an issue which seems related to these (...) posts, but isn't entirely the same as far as I can determine.

The issue is that when I change a form field that is subsequentlty validated by an Ajax request (see below for the xhtml code) and then select a different item that updates the entire form (thus without saving anything), the form fields that were change don't update.

For the snippet below this means that when I change the value of chemical.un, wait for the validation, and then change the overall chemical value (ie. select a different chemical), the value I have changed doesn't update (ie. 1005 stays 1005 instead of becoming 1020 after selecting a different item).

It seems like a jsf-lifecycle issue to me, but I might be entirely wrong. I would like to invalidate the model somehow, but don't know how to do it. But on the otherhand I might misunderstand the issue. Does anyone have an idea?

Thanks


<s:decorate id="chemicalUn" template="/layout/edit.xhtml">
	<h:inputText value="#{chemical.un}" required="true">
	<a:support event="onblur" reRender="chemicalUn" bypassUpdates="true" eventsQueue="queue" ajaxSingle="true">
		<s:conversationId/> 
	</a:support>
</s:decorate>


import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.faces.application.FacesMessage;
import javax.persistence.EntityManager;

import nl.chainsoftware.chemix.model.Chemical;
import nl.chainsoftware.chemix.model.ChemicalOverride;
import nl.chainsoftware.chemix.model.Compatibility;
import nl.chainsoftware.chemix.model.Material;
import nl.chainsoftware.chemix.model.TankgroupChemicalException;
import nl.chainsoftware.chemix.model.Translation;
import nl.chainsoftware.chemix.model.User;
import nl.chainsoftware.chemix.model.notes.ChemicalNote;
import nl.chainsoftware.chemix.model.notes.ChemicalNoteConnector;
import nl.chainsoftware.chemix.util.ListLocaleSelector;
import nl.chainsoftware.chemix.util.NoteSelectItem;

import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.security.Restrict;
import org.jboss.seam.core.Events;
import org.jboss.seam.annotations.Factory;

import org.jboss.seam.log.Log;
import org.jboss.seam.faces.FacesMessages;

@Stateful
@Name("chemicalManager")
@Restrict("#{identity.loggedIn}")
public class ChemicalManagerBean implements ChemicalManager {
	
    @Logger 
    private Log log;
	
    @In 
    FacesMessages facesMessages;
    
    @In(create=true)
    ListLocaleSelector listLocaleSelector;
    
    @In
    private EntityManager entityManager;
    
    @In(create=true)
    @Out
    private Chemical chemical;
		
    @In
	private Events events;    
    
    @In
    private User currentUser;
    
    @In(create=true)
    @Out
    private List<NoteSelectItem> notes;
    
    @In(required=false)
    @Out(required=false)
    private ChemicalOverride override;
    
    @Begin(join=true)
	public void select(Chemical selectedChemical) {
		log.info("ChemicalManager.select() called with chemical id: " + selectedChemical.getId());
		
		chemical = selectedChemical;
		
		checkLanguages();
		findNotes();
		
		facesMessages.addFromResourceBundle("#{messages['chemical.selected']}");
		
		log.info("ChemicalManager.select() exited with chemical id: " + selectedChemical.getId());

	}
}

6 Replies:
03. Oct 2008, 12:27 CET | Link

one of the other posts was this one:

http://www.seamframework.org/Community/AJAXFormInputsAreNotUpdatedPostValidationFailure

03. Oct 2008, 13:01 CET | Link

Show the rest of your page code. What changes the chemical?

03. Oct 2008, 14:28 CET | Link

(I am including everything one by one as I have difficulties submitting)

This is the full code (xhtml pages, javabean)

This show a list of chemicals and allows to select one of them to refresh/reload the form in the middle.


<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:s="http://jboss.com/products/seam/taglib"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:a="http://richfaces.org/a4j"
	xmlns:rich="http://richfaces.org/rich"
	xmlns:chemix="http://www.chainsoftware.nl/chemix"
	template="layout/template.xhtml">

	<ui:define name="left">
		<rich:panel id="leftSideMenu">
			<f:facet name="header">
				#{messages.Chemical}
			</f:facet>
			<h:graphicImage value="/img/chemical.jpg" width="100%" />
			<rich:spacer height="20px" />
			<s:link view="/overrideListManager.xhtml" value="#{messages['overrideList.manager']}" /> <br />
			<s:link view="/removalListManager.xhtml" value="#{messages['removalList.manager']}" />
		</rich:panel>
	</ui:define>

	<ui:define name="body">
		<rich:effect name="showTrans" for="translationsHolder" type="Appear" />
		<rich:effect name="hideTrans" for="translationsHolder" type="Fade" />
		<a:outputPanel id="chemicaldetail">
			<ui:include src="detail/chemicalDetail.xhtml" />
		</a:outputPanel>
	</ui:define>

	<ui:define name="right">
		<a:form id="chemicallist">
			<div id="itemList">
				<ui:repeat value="#{chemicals}" var="c">
					<div class="item" id="item-#{c.id}">
							<div class="un">#{c.un} - </div>
							<div class="chemicalName">
								<a:commandLink reRender="chemicaldetail" action="#{chemicalManager.select(c)}" onclick="highlightItem(this); " eventsQueue="queue" ajaxSingle="true" oncomplete="setEventHandlers();">
									<chemix:translation language="#{localeSelector.language}" value="#{c.translations}" />
								</a:commandLink>
							</div>			
					</div>
				</ui:repeat>
			</div>
		</a:form>
	</ui:define>
	
</ui:composition>
03. Oct 2008, 14:31 CET | Link

The form


<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:s="http://jboss.com/products/seam/taglib"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:a="http://richfaces.org/a4j"
	xmlns:c="http://java.sun.com/jstl/core"
	xmlns:rich="http://richfaces.org/rich"
	xmlns:chemix="http://www.chainsoftware.nl/chemix">

		<script language="javascript">
		var translations_show = false;
		
		function translations() {
			if (!translations_show) {
				showTrans({duration:0.7});
				translations_show = true;
			} else { 
				hideTrans();
				translations_show = false;
			}
			
			return false;
		}
		</script>
		
		<h:form id="chemicalForm" name="chemicalForm">
			
		<div class="messages">
			<rich:messages globalOnly="true" errorClass="errorMessage" infoClass="infoMessage"/>
		</div>
		 			 
		<s:validateAll>
			
  		<chemix:actionButtons oncomplete="setHighlightedItem(#{chemical.id})" backingBean="#{chemicalManager}" searchPage="/chemicalManager.xhtml" reRender="chemicaldetail,chemicallist">
  			<chemix:dropDownMenu>
				<chemix:dropDownMenuItem enabled="false">#{messages['dropDownMenu.moreActions']}</chemix:dropDownMenuItem>			
				<chemix:dropDownMenuItem>
					<a:commandLink
						ajaxSingle="true"
						eventsQueue="queue"
						reRender="chemicaldetail,chemicallist"
                        action="#{chemicalManager.remove}"
                        rendered="#{chemicalManager.managed}"
                        onclick="if(!confirm('#{messages['sureToRemoveThisItem']}')){return false;}"
                        oncomplete="clearForm('#chemicalForm');">
                        #{messages['chemical.delete']} 
                    </a:commandLink>
				</chemix:dropDownMenuItem>
				<chemix:dropDownMenuItem>
				 	<a:commandLink 
						ajaxSingle="true" 
						eventsQueue="queue"
						reRender="chemicaldetail"
						action="#{chemicalManager.copy}" 
						rendered="#{chemicalManager.managed}">
						#{messages['chemical.makeCopy']} 
					</a:commandLink>
				</chemix:dropDownMenuItem>
				<chemix:dropDownMenuItem enabled="false">#{messages['overrideList.addOverrideToLists']}</chemix:dropDownMenuItem>
				<ui:repeat value="#{overrideLists}" var="list">
					<chemix:dropDownMenuItem>
				 		<a:commandLink 
							ajaxSingle="true" 
							eventsQueue="queue"
							reRender="chemicaldetail"
							action="#{chemicalOverrideManager.addOverrideToList(list, chemical)}" 
							rendered="#{chemicalManager.managed}">
							@#{list.name} 
						</a:commandLink>
					</chemix:dropDownMenuItem>
				</ui:repeat>
			</chemix:dropDownMenu>
		</chemix:actionButtons>	
				
		<rich:tabPanel switchType="client">
		<rich:tab label="#{messages['chemical.details']}">
		
		<table cellpadding="0" cellspacing="1" border="0" class="properties" styleClass="chemicalProperties" width="100%">
			<col width="250px" />
			<col />
			<tbody>
			
				<tr>
					<td>#{messages['chemical.un']}</td>
					<td>
						<s:decorate id="chemicalUn" template="/layout/edit.xhtml">
						<h:inputText value="#{chemical.un}" required="true">
							<a:support event="onblur" reRender="chemicalUn" bypassUpdates="true" eventsQueue="queue" ajaxSingle="true">
								<s:conversationId/> 
							</a:support>
						</h:inputText>
						</s:decorate>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.name']}</td>
					<td>
						<a href="#" onclick="translations();">
							<h:graphicImage value="img/edit-add.png" style="border: none"/>
						</a>
						<chemix:translation language="#{listLocaleSelector.language}" value="#{chemical.translations}" />
						<div id="translationsHolder" style="display:none">
						<a:outputPanel id="translations" styleClass="translations" layout="block">
							<table width="100%" border="0">
							<ui:repeat value="#{chemical.translations}" var="translation">
								<tr>
									<td>#{translation.language}:</td>
									<td><h:inputTextarea value="#{translation.name}" cols="60" rows="5" /></td>
								</tr>
							</ui:repeat>
							</table>
						</a:outputPanel>
						</div>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.class']}</td>
					<td>
						<s:decorate id="chemicalClassification" template="/layout/edit.xhtml">
						<h:inputText value="#{chemical.classification}" required="true">
							<a:support event="onblur" reRender="chemicalClassification" bypassUpdates="true" eventsQueue="queue" ajaxSingle="true">
								<s:conversationId/> 
							</a:support>
						</h:inputText>
						</s:decorate>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.classificationCode']}</td>
					<td>
						<s:decorate id="chemicalClassificationCode" template="/layout/edit.xhtml">
						<h:inputText value="#{chemical.classificationCode}" required="true">
							<a:support event="onblur" reRender="chemicalClassificationCode" bypassUpdates="true" eventsQueue="queue" ajaxSingle="true">
								<s:conversationId/> 
							</a:support>
						</h:inputText>
						</s:decorate>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.packingGroup']}</td>
					<td>
						<s:decorate id="chemicalPackageGroup" template="/layout/edit.xhtml">
						<h:inputText value="#{chemical.packageGroup}">
							<a:support event="onblur" reRender="chemicalPackageGroup" bypassUpdates="true" eventsQueue="queue" ajaxSingle="true">
								<s:conversationId/> 
							</a:support>
						</h:inputText>
						</s:decorate>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.dangers']}</td>
					<td>
						<h:selectManyCheckbox value="#{chemical.dangers}" layout="pageDirection">
							<s:selectItems value="#{enumLists.dangers}" var="danger" label="#{danger.code}"/>
							<s:convertEnum />
						</h:selectManyCheckbox>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.tankerType']}</td>
					<td>
						<h:selectOneMenu value="#{chemical.tankType}">
							<s:selectItems value="#{enumLists.tankTypes}" var="type" label="#{type}" />
 							<s:convertEnum />
        				</h:selectOneMenu>
        			</td>
				</tr>
				<tr>
					<td>#{messages['chemical.tankCondition']}</td>
					<td>
						<h:selectOneMenu value="#{chemical.tankCondition}">
							<s:selectItems value="#{enumLists.conditions}" var="c" label="#{messages[c.key]}" />
							<s:convertEnum />
        				</h:selectOneMenu>						
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.hullType']}</td>
					<td>
						<h:selectOneMenu value="#{chemical.hullType}">
							<s:selectItems value="#{enumLists.hullTypes}" var="dev" label="#{messages[dev.key]}" />
							<s:convertEnum />
        				</h:selectOneMenu>						
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.tankEquipment']}</td>
					<td>
						<h:selectOneMenu value="#{chemical.tankEquipment}">
							<s:selectItems value="#{enumLists.tankEquipment}" var="e" label="#{messages[e.key]}" noSelectionLabel="#{messages['notAvailable']}" />
							<s:convertEnum />
        				</h:selectOneMenu>						
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.relievePressure']}</td>
					<td>
						<s:decorate id="chemicalRelievePressure" template="/layout/edit.xhtml">
						<h:inputText value="#{chemical.relievePressure}" required="true">
							<a:support event="onblur" reRender="chemicalRelievePressure" bypassUpdates="true" eventsQueue="queue" ajaxSingle="true">
								<s:conversationId/> 
							</a:support>
						</h:inputText>
						</s:decorate>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.maxFillRate']}</td>
					<td>
						<s:decorate id="chemicalMaxFillRate" template="/layout/edit.xhtml">
						<h:inputText value="#{chemical.maxFillRate}" required="true">
							<a:support event="onblur" reRender="chemicalMaxFillRate" bypassUpdates="true" eventsQueue="queue" ajaxSingle="true">
								<s:conversationId/> 
							</a:support>
						</h:inputText>
						</s:decorate>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.densityAt20C']}</td>
					<td>
						<s:decorate id="chemicalDensity" template="/layout/edit.xhtml">
						<h:inputText value="#{chemical.density}" required="true">
							<a:support event="onblur" reRender="chemicalDensity" bypassUpdates="true" eventsQueue="queue" ajaxSingle="true">
								<s:conversationId/> 
							</a:support>
						</h:inputText>
						</s:decorate>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.samplingDevice']}</td>
					<td>
						<h:selectOneMenu value="#{chemical.samplingDevice}">
							<s:selectItems value="#{enumLists.samplingDevices}" var="dev" label="#{messages[dev.key]}" />
							<s:convertEnum />
        				</h:selectOneMenu>						
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.allowUnderdeckPumproom']}</td>
					<td><h:selectBooleanCheckbox value="#{chemical.allowPumpRoom}" /></td>
				</tr>
				<tr>
					<td>#{messages['chemical.temperatureClass']}</td>
					<td>
						<h:selectOneMenu value="#{chemical.temperatureClass}">
							<s:selectItems value="#{enumLists.temperatureClasses}" var="class" label="#{class}" noSelectionLabel="No temperature class"/>
 							<s:convertEnum />
        				</h:selectOneMenu>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.explosionGroups']}</td>
					<td>
						<h:selectOneMenu value="#{chemical.explosionGroup}">
							<s:selectItems value="#{enumLists.explosionGroups}" var="group" label="#{group}" noSelectionLabel="No explosion group"/>
 							<s:convertEnum />
        				</h:selectOneMenu>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.explosionProtectionRequired']}</td>
					<td><h:selectBooleanCheckbox value="#{chemical.explosionProtection}" /></td>
				</tr>
				<tr>
					<td>#{messages['chemical.requiredEquipment']}</td>
					<td>
						<h:selectManyCheckbox value="#{chemical.equipment}">
							<s:selectItems value="#{enumLists.equipment}" var="item" label="#{item}"/>
							<s:convertEnum />
						</h:selectManyCheckbox>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.nrBlueLights']}</td>
					<td>
						<s:decorate id="chemicalBlueLights" template="/layout/edit.xhtml">
						<h:inputText value="#{chemical.bluelights}" required="true">
							<a:support event="onblur" reRender="chemicalBlueLights" bypassUpdates="true" eventsQueue="queue" ajaxSingle="true">
								<s:conversationId/> 
							</a:support>
						</h:inputText>
						</s:decorate>
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.useOverrideOnly']}</td>
					<td>
						<h:selectBooleanCheckbox value="#{chemical.overrideOnly}" />
					</td>
				</tr>
				<tr>
					<td>#{messages['chemical.hasMultiplePositions']}</td>
					<td>
						<h:selectBooleanCheckbox value="#{chemical.multiplePositions}" />
					</td>
				</tr>				
				
			</tbody>
		</table>
		</rich:tab>
		<rich:tab label="#{messages['chemical.compatibility']}">
		<table cellpadding="0" cellspacing="1" border="0" class="properties">
			<tbody>
				<ui:repeat value="#{chemical.compatibility}" var="c">
				<tr>
					<td>#{c.material.commonName}</td>
					<td>
						<h:selectOneMenu value="#{c.compatibilityStatus}">
							<s:selectItems value="#{enumLists.status}" var="z" label="#{messages[z.key]}" />
							<s:convertEnum />
        				</h:selectOneMenu>						
					</td>
				</tr>
				</ui:repeat>
			</tbody>
		</table>
		</rich:tab>
		<rich:tab label="#{messages['chemical.notes']}">
			<ui:repeat value="#{notes}" var="note">
				<div class="chemicalNote">
					<div class="chemicalNoteCheckbox"><h:selectBooleanCheckbox value="#{note.selected}" onclick="changeTFstatus(this);" /></div> 
					<div class="chemicalNoteLabel">#{note.label}</div>
					<div class="chemicalNoteTxT"><h:inputText value="#{note.extra}" disabled="#{!note.selected}" /></div>
				</div>
			</ui:repeat>
		</rich:tab>
		<rich:tab label="#{messages['chemical.internalNotes']}">
			<h:inputTextarea value="#{chemical.internalNote}" cols="100" rows="20"/>
		</rich:tab>		
		<c:if test="${!empty chemical.overrides}">
			<rich:tab label="#{messages['chemical.overrides']}">
				<div id="chemicalOverridesTab">
				</div>
			</rich:tab>		
		</c:if>
		</rich:tabPanel>
		</s:validateAll>
		</h:form>
		
		<ui:include src="/detail/editOverridePanel.xhtml" >
		   <ui:param name="refresh" value="chemicaldetail"/>
		</ui:include>

		<c:if test="${!empty chemical.overrides}">
				<script type="text/javascript" language="javascript">
					var names = [
						"#{messages['overrideList.name']}",
						"#{messages['chemical.un']}",
						"#{messages['chemical.name']}",
						"#{messages['chemical.class']}",
						"#{messages['chemical.classificationCode']}",
						"#{messages['chemical.packingGroup']}",
						"#{messages['chemical.dangers']}",
						"#{messages['chemical.tankerType']}",
						"#{messages['chemical.tankCondition']}",
						"#{messages['chemical.hullType']}",
						"#{messages['chemical.tankEquipment']}",
						"#{messages['chemical.tankCondition']}",
						"#{messages['chemical.hullType']}",
						"#{messages['chemical.tankEquipment']}",
						"#{messages['chemical.relievePressure']}",
						"#{messages['chemical.maxFillRate']}",
						"#{messages['chemical.densityAt20C']}",
						"#{messages['chemical.samplingDevice']}",
						"#{messages['chemical.allowUnderdeckPumproom']}",
						"#{messages['chemical.temperatureClass']}",
						"#{messages['chemical.explosionGroups']}",
						"#{messages['chemical.explosionProtectionRequired']}",
						"#{messages['chemical.requiredEquipment']}",
						"#{messages['chemical.nrBlueLights']}"
					];
					
					var table_data = [
					<ui:repeat value="#{chemical.overrides}" var="orl">
						"#{orl.overrideList.name}",
						"#{orl.un}",
						"<chemix:translation language="#{listLocaleSelector.language}" value="#{orl.translations}" />",
						"#{orl.classification}",
						"#{orl.classificationCode}",
						"#{orl.packageGroup}",
						"#{orl.dangers}",
						"#{orl.tankType}",
						"#{orl.tankCondition}",
						"#{orl.hullType}",
						"#{orl.tankEquipment}",
						"#{orl.relievePressure}",
						"#{orl.maxFillRate}",
						"#{orl.density}",
						"#{orl.samplingDevice}",
						"#{orl.allowPumpRoom}",
						"#{orl.temperatureClass}",
						"#{orl.explosionGroup}",
						"#{orl.explosionProtection}",
						"#{orl.equipment}",
						"#{orl.bluelights}"
					</ui:repeat>
					];
				</script>
		</c:if>
		
</ui:composition>
03. Oct 2008, 14:31 CET | Link

The javabean


package nl.chainsoftware.chemix.session;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.faces.application.FacesMessage;
import javax.persistence.EntityManager;

import nl.chainsoftware.chemix.model.Chemical;
import nl.chainsoftware.chemix.model.ChemicalOverride;
import nl.chainsoftware.chemix.model.Compatibility;
import nl.chainsoftware.chemix.model.Material;
import nl.chainsoftware.chemix.model.TankgroupChemicalException;
import nl.chainsoftware.chemix.model.Translation;
import nl.chainsoftware.chemix.model.User;
import nl.chainsoftware.chemix.model.notes.ChemicalNote;
import nl.chainsoftware.chemix.model.notes.ChemicalNoteConnector;
import nl.chainsoftware.chemix.util.ListLocaleSelector;
import nl.chainsoftware.chemix.util.NoteSelectItem;

import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.security.Restrict;
import org.jboss.seam.core.Events;
import org.jboss.seam.annotations.Factory;

import org.jboss.seam.log.Log;
import org.jboss.seam.faces.FacesMessages;

@Stateful
@Name("chemicalManager")
@Restrict("#{identity.loggedIn}")
public class ChemicalManagerBean implements ChemicalManager {
	
    @Logger 
    private Log log;
	
    @In 
    FacesMessages facesMessages;
    
    @In(create=true)
    ListLocaleSelector listLocaleSelector;
    
    @In
    private EntityManager entityManager;
    
    @In(create=true)
    @Out
    private Chemical chemical;
		
    @In
	private Events events;    
    
    @In
    private User currentUser;
    
    @In(create=true)
    @Out
    private List<NoteSelectItem> notes;
    
    @In(required=false)
    @Out(required=false)
    private ChemicalOverride override;
    
    @Begin(join=true)
	public void select(Chemical selectedChemical) {
		log.info("ChemicalManager.select() called with chemical id: " + selectedChemical.getId());
		
		chemical = selectedChemical;
		
		checkLanguages();
		findNotes();
		
		facesMessages.addFromResourceBundle("#{messages['chemical.selected']}");
		
		log.info("ChemicalManager.select() exited with chemical id: " + selectedChemical.getId());

	}

    @End
	public void persist() {
    	chemical.setUpdated(new Date());
    	chemical.setUpdatedby(currentUser);
    	
    	try {
    		setNotes();
    		entityManager.persist(chemical);
    		
    		facesMessages.addFromResourceBundle("#{messages['chemical.created']}");
    		log.info("Chemical created");
    	} catch (Exception e) {
			log.fatal("Could not create chemical (" + chemical.getId() + ") " + e);
			facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_ERROR, "#{messages['chemical.notCreated']}");   	
    	}
		
		events.raiseTransactionSuccessEvent("chemicalsUpdated");
	}
	
	@SuppressWarnings("unchecked")
	@End(beforeRedirect=true)
	public void remove() {
		log.info("chemicalManager.remove() called with chemical id: " + chemical.getId());
		
		try {
			/* This is necessary otherwise a remove fails with "deleted entity passed to persist"
			 * Should be move to one (material, chemical or compatibility) of the entities */
			List<Compatibility> comps = chemical.getCompatibility();
			for (Compatibility c : comps) {
				Material m = c.getMaterial();
				m.getCompatibilities().remove(c);
			}
			
			List<TankgroupChemicalException> exceptions = entityManager.createQuery("from TankgroupChemicalException where chemical.id = :id").setParameter("id", chemical.getId()).getResultList();
			for (TankgroupChemicalException e : exceptions) {
				entityManager.remove(e);
			}
			entityManager.remove(chemical);
			entityManager.flush();

			createChemical();
			
			facesMessages.addFromResourceBundle("#{messages['chemical.removed']}");
			log.info("Chemical removed");
		} catch (Exception e) {
			log.fatal("Could not remove chemical (" + chemical.getId() + ") " + e);
			facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_ERROR, "#{messages['chemical.notRemoved']}");		
		}
		
		events.raiseTransactionSuccessEvent("chemicalsUpdated");
	}
	
	/**
	 * Checks the chemical for available languages and adds one if necessary
	 */
	private void checkLanguages() {
		if (chemical == null)
			return;
		
		List<Translation> translations = chemical.getTranslations();
		
		Iterator<Locale> locales = listLocaleSelector.getListLocales();
		while (locales.hasNext()) {
			Locale locale = locales.next();
			if (!hasLanguage(locale.getLanguage())) {
				Translation t = new Translation(locale.getLanguage(), new String());
				t.setChemical(chemical);
				t.setUpdated(new Date());
				t.setUpdatedby(currentUser);
				translations.add(t);
			}
		}
	}
	
	public boolean isManaged() {
		if (chemical == null) 
			return false;
		
		if (!entityManager.contains(chemical))
			return false;
		
		return true;
	}
	
	@Remove
	public void destroy() {}

	private boolean hasLanguage(String language) {
		if (chemical.getTranslations() == null)
			return false;
		
		for (Translation t : chemical.getTranslations()) {
			if (t.getLanguage().equals(language))
				return true;
		}
		
		return false;
	}

	public void build() {
		// TODO Auto-generated method stub
		
	}

	public void update() {
		log.info("Saving chemical " + chemical.getId() + " (" + chemical.getUn() + ")");
		
		try {
			setNotes();
			entityManager.persist(chemical);
			facesMessages.addFromResourceBundle("#{messages['chemical.updated']}");
			log.info("Chemical saved");
		} catch (Exception e) {
			log.fatal("Could not save chemical (" + chemical.getId() + ") " + e);
			facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_ERROR, "#{messages['chemical.notUpdated']}");
			
			revert();			
		}
		events.raiseTransactionSuccessEvent("chemicalsUpdated");		
	}
	
	private void revert() {
		chemical = entityManager.find(Chemical.class, chemical.getId());
	}
	
	@Factory("chemical")
	@SuppressWarnings("unchecked")
	public Chemical createChemical() {
		log.info("Creating new chemical");
		
		chemical = new Chemical();
		
		List<Compatibility> compatibilityList = new ArrayList<Compatibility>();
		List<Material> materials = entityManager.createQuery("from Material").getResultList();
		
		for (Material material : materials) {
			Compatibility c = new Compatibility(chemical, material);
			compatibilityList.add(c);
		}
		chemical.setCompatibility(compatibilityList);
		
		List<Translation> translations = new ArrayList<Translation>();
		
	    Iterator<Locale> locales = listLocaleSelector.getListLocales();
	    while ( locales.hasNext() ) {
	    	Locale locale = locales.next();
	    	Translation t = new Translation();
	    	t.setLanguage(locale.getLanguage());
	    	t.setChemical(chemical);
	    	t.setUpdated(new Date());
	    	t.setUpdatedby(currentUser);
	    	translations.add(t);
	    }
		chemical.setTranslations(translations);
		
		return chemical;
	}
	
	/**
	 * do a deep copy of a chemical
	 */
	public void copy() {
		Chemical copy = new Chemical();
		
		copy.setAllowPumpRoom(chemical.isAllowPumpRoom());
		copy.setBluelights(chemical.getBluelights());
		copy.setClassification(chemical.getClassification());
		copy.setClassificationCode("[copy]" + chemical.getClassificationCode());
		copy.setDensity(chemical.getDensity());
		
		// TODO: check if this does not raise an issue with the chemical being copied
		copy.setExplosionGroup(chemical.getExplosionGroup());
		copy.setExplosionProtection(chemical.isExplosionProtection());
		copy.setHullType(chemical.getHullType());
		copy.setInternalNote(chemical.getInternalNote());
		copy.setMaxFillRate(chemical.getMaxFillRate());
		copy.setPackageGroup(chemical.getPackageGroup());
		copy.setRelievePressure(chemical.getRelievePressure());
		copy.setTankCondition(chemical.getTankCondition());
		copy.setTemperatureClass(chemical.getTemperatureClass());
		copy.setTankType(chemical.getTankType());
		copy.setSamplingDevice(chemical.getSamplingDevice());
		copy.setUn(chemical.getUn());
		copy.setUpdated(new Date());
		copy.setUpdatedby(currentUser);
		
		List<Translation> translations = new ArrayList<Translation>();
		for (Translation t : chemical.getTranslations()) {
			Translation tc = new Translation();
			tc.setChemical(copy);
			tc.setLanguage(t.getLanguage());
			tc.setName("[copy]" + t.getName());
			tc.setUpdated(new Date());
			tc.setUpdatedby(currentUser);
			translations.add(tc);
		}
		copy.setTranslations(translations);
		
		List<Compatibility> compatibilities = new ArrayList<Compatibility>();
		for (Compatibility c : chemical.getCompatibility()) {
			Compatibility cc = new Compatibility();
			cc.setChemical(copy);
			cc.setCompatibilityStatus(c.getCompatibilityStatus());
			cc.setListName(c.getListName());
			cc.setMaterial(c.getMaterial());
			cc.setNote(c.getNote());
			cc.setUpdated(new Date());
			compatibilities.add(cc);
		}
		copy.setCompatibility(compatibilities);
		
		List<ChemicalNoteConnector> connectors = new ArrayList<ChemicalNoteConnector>();
		for (ChemicalNoteConnector c : chemical.getNotes()) {
			ChemicalNoteConnector connector = new ChemicalNoteConnector();
			connector.setChemical(copy);
			connector.setChemicalNote(c.getChemicalNote());
			connector.setExtra(c.getExtra());
			connectors.add(connector);
		}
		copy.setNotes(connectors);
		
		chemical = copy;
	}
	
	@Factory("notes")
	@SuppressWarnings("unchecked")
	public List<NoteSelectItem> findNotes() {
		if (chemical == null)
			return null;
		
		List<ChemicalNoteConnector> connectedNotes;
		if (entityManager.contains(chemical)) {
			connectedNotes = 
				entityManager.createQuery("from ChemicalNoteConnector cnn where cnn.chemical = :chemical")
				.setParameter("chemical", chemical)
				.getResultList();
		} else {
			connectedNotes = new ArrayList<ChemicalNoteConnector>();
		}
		
		List<ChemicalNote> notesList = entityManager.createQuery("from ChemicalNote c order by c.number asc").getResultList();
		
		List<NoteSelectItem> items = new ArrayList<NoteSelectItem>();
		for (ChemicalNote n : notesList) {
			NoteSelectItem item = new NoteSelectItem();
			item.setLabel(Integer.toString(n.getNumber()));
			item.setValue(n);
			for (ChemicalNoteConnector cnn : connectedNotes) {
				if (cnn.getChemicalNote().getNumber() == n.getNumber()) {
					item.setSelected(true);
					item.setExtra(cnn.getExtra());
					break;
				}	
			}
			items.add(item);
		}
		
		notes = items;
		
		return notes;
	}
	
	private void setNotes() {
		log.info("chemicalManager.setNotes called");
		
		if (entityManager.contains(chemical)) {
			for (ChemicalNoteConnector nc : chemical.getNotes()) {
				nc.getChemicalNote().getChemicals().remove(nc);
				entityManager.remove(nc);
			}
			chemical.setNotes(null);
			entityManager.flush();
		}
		
		List<ChemicalNoteConnector> connectors = new ArrayList<ChemicalNoteConnector>();
		for (NoteSelectItem item : notes) {
			if (!item.isSelected())
				continue;
			log.info("Adding connector: " + item.getLabel() + " extra: " + item.getExtra());
			ChemicalNoteConnector connector = new ChemicalNoteConnector();
			connector.setChemical(chemical);
			connector.setChemicalNote((ChemicalNote) item.getValue());
			connector.setExtra(item.getExtra());
			
			connectors.add(connector);
		}
		chemical.setNotes(connectors);
	}
	
	public void getOverrideFromList(ChemicalOverride override) {
		if (override == null) {
			log.warn("getOverrideFromList: got null");
			return;
		}
		
		this.override = override;
	}

}
03. Oct 2008, 16:25 CET | Link

Ouch. It's nicer for everyone involved if you can cut your problem down to a smaller size and then we can work on it. Why not try cutting it down to the basics (ie one very simple bean and one simple page) and see if you can reproduce? Then once proven/fixed you can build it back into your actual code.

Are you saying that the none of the chemical values are updating when you select a new chemical or just that a few aren't updating?

If the former then try removing the @Factory("chemical") and just referring to the chemical as #{chemicalManager.chemical} in your page. See if that helps.

If the latter then you'll need to look into using <a4j:region> (often inputTexts don't reRender well without the use of regions)

Cheers,

Damian.