0 Replies Latest reply on May 19, 2008 9:49 AM by Bolke de Bruin

    Why is my conversationId incremented or understanding conversations

    Bolke de Bruin Newbie

      Hi,


      I am having trouble understanding why a conversationid is incremented sometimes and (?) resulting in the dreaded LazyInitalization. Or in other words why do I end up with a LazyInitalizationException when I do not expect to have left the conversation? Please excuse me if this a question asked before: I did search but I am having trouble applying possible solutions to my situation. So thanks for looking at it.


      The setup is quite simple. A logged in user is able to select an Item from a List which is then displayed. This all happens with Ajax calls so the page itself is never fully updated. I have structured the components as follows. The list is contained in a SessionBean, the selected item is scoped Conversation. If I select an Item from the list I often (not always!) receive a LazyInitalizationException on one of the properties of the Item. I don't understand why. The documentation says, afaik, the LazyInitalizationExceptions occur when accessing properties from a different conversation than the current one. For me the question is when did I leave the converstation and why?. Furthermore, would an EntityHome pattern solve this?



      Below is the 'holderpage':



      <ui:define name="right">
                <a:form id="chemicallist">
                     <div id="itemList">
                          <ui:repeat value="#{chemicals}" var="c">
                               <div class="item">
                                    <div class="un">#{c.un} - </div>
                                    <div class="chemicalName">
                                         <a:commandLink reRender="chemicaldetail" action="#{chemicalManager.select(c)}" onclick="highlightItem(this);" eventsQueue="chemicalsProcessor" ajaxSingle="true">
                                              <chemix:translation language="#{localeSelector.language}" value="#{c.translations}" />
                                         </a:commandLink>
                                    </div>
                               </div>
                          </ui:repeat>
                     </div>
                </a:form>
           </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>
      
      



      This is the detail page:



      <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>
                     <div class="messages">
                          <rich:messages errorClass="errorMessage" infoClass="infoMessage"/>
                      </div>
                       <chemix:actionButtons backingBean="#{chemicalManager}" searchPage="/chemicalManager.xhtml" reRender="chemicalDetail" /> 
                
                          
                <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}">
                                         <a:support event="onblur" reRender="chemicalUn" bypassUpdates="true"/>
                                    </h:inputText>
                                    </s:decorate>
                               </td>
                          </tr>
                          <tr>
                               <td>#{messages['chemical.name']}</td>
                               <td>
                                    <a href="#" onclick="translations();">
                                         <h:graphicImage value="img/arrow_forward_details.gif" style="border: none"/>
                                    </a>
                                    <chemix:translation language="#{localeSelector.language}" value="#{chemical.translations}" />
                                    <div id="translationsHolder" style="display:none">
                                    <a:outputPanel id="translations" styleClass="translations" layout="block">
                                         <c:if test="${!empty chemical}">
                                              <div id="translationsHeader">
                                              <a:commandButton value="#{messages['chemical.addMissingLanguage']}" reRender="translations" />
                                              <h:selectOneMenu>
                                                   <s:selectItems value="#{chemicalManager.missingLanguages}" var="lang" label="#{lang}" noSelectionLabel="#{messages['chemical.noMissingLanguage']}" />
                                              </h:selectOneMenu>
                                              </div>
                                         </c:if>                                   
                                         <table width="100%" border="0">
                                         <ui:repeat value="#{chemical.translations}" var="trans">
                                              <tr>
                                                   <td>#{trans.language}:</td>
                                                   <td><h:inputTextarea value="#{trans.name}" cols="60" rows="5"/></td>
                                              </tr>
                                         </ui:repeat>
                                         </table>
                                    </a:outputPanel>
                                    </div>
                               </td>
                          </tr>
                          <tr>
                               <td>#{messages['chemical.classificationCode']}</td>
                               <td>
                                    <s:decorate id="chemicalClassificationCode" template="/layout/edit.xhtml">
                                    <h:inputText value="#{chemical.classificationCode}">
                                         <a:support event="onblur" reRender="chemicalClassificationCode" bypassUpdates="true"/>
                                    </h:inputText>
                                    </s:decorate>
                               </td>
                          </tr>
                          <tr>
                               <td>#{messages['chemical.class']}</td>
                               <td>
                                    <s:decorate id="chemicalClassification" template="/layout/edit.xhtml">
                                    <h:inputText value="#{chemical.classification}">
                                         <a:support event="onblur" reRender="chemicalClassification" bypassUpdates="true"/>
                                    </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"/>
                                    </h:inputText>
                                    </s:decorate>
                               </td>
                          </tr>
                          <tr>
                               <td>#{messages['chemical.explosionProtectionRequired']}</td>
                               <td><h:selectBooleanCheckbox value="#{chemical.explosionProtection}" /></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.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.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.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.densityAt20C']}</td>
                               <td>
                                    <s:decorate id="chemicalDensity" template="/layout/edit.xhtml">
                                    <h:inputText value="#{chemical.density}">
                                         <a:support event="onblur" reRender="chemicalDensity" bypassUpdates="true"/>
                                    </h:inputText>
                                    </s:decorate>
                               </td>
                          </tr>
                          <tr>
                               <td>#{messages['chemical.nrBlueLights']}</td>
                               <td>
                                    <s:decorate id="chemicalBlueLights" template="/layout/edit.xhtml">
                                    <h:inputText value="#{chemical.bluelights}">
                                         <a:support event="onblur" reRender="chemicalBlueLights" bypassUpdates="true"/>
                                    </h:inputText>
                                    </s:decorate>
                               </td>
                          </tr>
                          <tr>
                               <td>#{messages['chemical.allowUnderdeckPumproom']}</td>
                               <td><h:selectBooleanCheckbox value="#{chemical.allowPumpRoom}" /></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.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="Not Available" />
                                         <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}">
                                         <a:support event="onblur" reRender="chemicalRelievePressure" bypassUpdates="true"/>
                                    </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}">
                                         <a:support event="onblur" reRender="chemicalMaxFillRate" bypassUpdates="true"/>
                                    </h:inputText>
                                    </s:decorate>
                               </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.symbol}</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']}">
                <table cellpadding="0" cellspacing="1" border="0" class="properties">
                     <tbody>
                          <ui:repeat value="#{chemical.notes}" var="note">
                          <tr>
                               <td>xx: #{note.number}</td>
                          </tr>
                          </ui:repeat>
                     </tbody>
                </table>
                </rich:tab>
                <rich:tab label="#{messages['chemical.internalNotes']}">
                     <h:inputTextarea value="#{chemical.internalNote}" cols="100" rows="20"/>
                </rich:tab>          
                </rich:tabPanel>
                </h:form>
      </ui:composition>
      
      



      This is the SessionBean:



      @Stateful
      @Scope(SESSION)
      @Name("chemicalList")
      @Restrict("#{identity.loggedIn}")
      public class ChemicalListAction implements ChemicalList, Serializable {
      
           private static final long serialVersionUID = 1L;
      
           @Logger private Log log;
           
           @In
           EntityManager entityManager;
           
           @DataModel
           private List<Chemical> chemicals;
           
           @DataModelSelection
           private Chemical chemical;
           
           @Override
           public Chemical getChemical() {
                return chemical;
           }
      
           @Override
           @SuppressWarnings("unchecked")
           @Factory
           @Observer("chemicalsUpdated")
           public void getChemicals() {
                log.info("ChemicalList.getChemicals() called");
                
                chemicals = entityManager.createQuery("from Chemical c order by c.un")
                     .getResultList();
                
                log.info("Finished retrieving chemicals");
      
           }
      
           @Override
           @Destroy @Remove
           public void destroy() {
           }
      
      }
      



      The ConversationBean:



      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.context.FacesContext;
      import javax.persistence.EntityManager;
      
      import nl.chainsoftware.chemix.model.Chemical;
      import nl.chainsoftware.chemix.model.Compatibility;
      import nl.chainsoftware.chemix.model.Material;
      import nl.chainsoftware.chemix.model.Translation;
      import nl.chainsoftware.chemix.model.User;
      
      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
          private EntityManager entityManager;
          
          @In(required=false)
          @Out
          private Chemical chemical;
                
          @In
           private Events events;    
          
          @In
          private User currentUser;
          
            public void select(Chemical selectedChemical) {
                log.info("ChemicalManager.select() called with chemical id: " + selectedChemical.getId());
                
                chemical = selectedChemical;
      
                log.info("ChemicalManager.select() exited with chemical id: " + selectedChemical.getId());
      
           }
      
            public void persist() {
                 log.info("Saving new chemical");
                 
               chemical.setUpdated(new Date());
               chemical.setUpdatedby(currentUser);
               
                entityManager.persist(chemical);
                
                // TODO: raise transaction success event
           }
           
           public void remove() {
                log.info("chemicalManager.remove() called with chemical id: " + chemical.getId());
                
                /* This is necessary otherwise a remove fails with "deleted entity passed to persist"
                 * Should be moved 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);
                }
                          
                entityManager.remove(chemical);
                entityManager.flush();
      
                createChemical();
                
                events.raiseTransactionSuccessEvent("chemicalsUpdated");
           }
           
           public List<Locale> getMissingLanguages() {
                if (chemical == null)
                     return null;
                
                List<Locale> lang = new ArrayList<Locale>();
               Iterator<Locale> locales = FacesContext.getCurrentInstance().getApplication().getSupportedLocales();
               while ( locales.hasNext() ) {
                    Locale locale = locales.next();
                    if (!hasLanguage(locale.getLanguage()))
                         lang.add(locale);
               }
               
               return lang;
           }
      
           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;
           }
      
           @Override
           public void build() {
                // TODO Auto-generated method stub
                
           }
      
           @Override
           public void update() {
                log.info("Saving chemical " + chemical.getId());
                
                try {
                     entityManager.persist(chemical);
                     facesMessages.add("Chemical has been saved");
                     log.info("Chemical saved");
                } catch (Exception e) {
                     log.fatal("Could not save chemical (" + chemical.getId() + ") " + e);
                     facesMessages.add("Something went wrong. Your chemical has NOT been saved");
                     
                     revert();               
                }
           }
           
           private void revert() {
                chemical = entityManager.find(Chemical.class, chemical.getId());
           }
      
           @Factory("chemical")
           @SuppressWarnings("unchecked")
           public void 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);
           }
      }
      
      
      



      and the Entity itself:



      @Entity
      @Name("chemical")
      public class Chemical implements Serializable {
           private static final long serialVersionUID = -81501463360195381L;
      
           private int id;
           private int un;
           
           private int maxFillRate;
           private boolean allowPumpRoom;
           private TemperatureClass temperatureClass;
           private boolean explosionProtection;
           private double density;
           private String classification;
           private int relievePressure;
           
           private Date updated;
           private User updatedby;
           
           private String classificationCode;
           private String packageGroup;
           
           private int bluelights;
           
           private List<ChemicalNoteConnector> notes;
           private List<Compatibility> compatibility;
           private List<Danger> dangers;
           private List<Equipment> equipment;
           
           private SamplingDevice samplingDevice;
           
           private List<Translation> translations;
           
           private TankType tankType;
           private HullType hullType;
           private ExplosionGroup explosionGroup;
           
           private TankEquipment tankEquipment;
           
           private Condition tankCondition;
           
           private String internalNote;
           
           @Id
           @GeneratedValue(strategy = GenerationType.AUTO)
           public int getId() {
                return id;
           }
      
           public void setId(int id) {
                this.id = id;
           }
      
           @Min(value=1)
           public int getUn() {
                return un;
           }
      
           public void setUn(int un) {
                this.un = un;
           }
      
           @Range(min=0, max=100)
           public int getMaxFillRate() {
                return maxFillRate;
           }
      
           public void setMaxFillRate(int maxFillRate) {
                this.maxFillRate = maxFillRate;
           }
      
           public boolean isAllowPumpRoom() {
                return allowPumpRoom;
           }
      
           public void setAllowPumpRoom(boolean allowPumpRoom) {
                this.allowPumpRoom = allowPumpRoom;
           }
      
           public TemperatureClass getTemperatureClass() {
                return temperatureClass;
           }
      
           public void setTemperatureClass(TemperatureClass temperatureClass) {
                this.temperatureClass = temperatureClass;
           }
      
           public boolean isExplosionProtection() {
                return explosionProtection;
           }
      
           public void setExplosionProtection(boolean explosionProtection) {
                this.explosionProtection = explosionProtection;
           }
      
           @Min(value=0)
           public double getDensity() {
                return density;
           }
      
           public void setDensity(double density) {
                this.density = density;
           }
      
           public String getClassification() {
                return classification;
           }
      
           public void setClassification(String classification) {
                this.classification = classification;
           }
      
           @Min(value=0)
           public int getRelievePressure() {
                return relievePressure;
           }
      
           public void setRelievePressure(int relievePressure) {
                this.relievePressure = relievePressure;
           }
      
           public Date getUpdated() {
                return updated;
           }
      
           public void setUpdated(Date updated) {
                this.updated = updated;
           }
      
           @ManyToOne
           @NotNull
           public User getUpdatedby() {
                return updatedby;
           }
      
           public void setUpdatedby(User updatedby) {
                this.updatedby = updatedby;
           }
      
           public String getClassificationCode() {
                return classificationCode;
           }
      
           public void setClassificationCode(String classificationCode) {
                this.classificationCode = classificationCode;
           }
      
           public String getPackageGroup() {
                return packageGroup;
           }
      
           public void setPackageGroup(String packageGroup) {
                this.packageGroup = packageGroup;
           }
      
           @Min(value=0)
           public int getBluelights() {
                return bluelights;
           }
      
           public void setBluelights(int bluelights) {
                this.bluelights = bluelights;
           }
           
           @OneToMany(mappedBy="chemical")
           public List<ChemicalNoteConnector> getNotes() {
                return notes;
           }
           
           public void setNotes(List<ChemicalNoteConnector> notes) {
                this.notes = notes;
           }
      
           @OneToMany(mappedBy="chemical", cascade=CascadeType.ALL)
           public List<Compatibility> getCompatibility() {
                return compatibility;
           }
      
           public void setCompatibility(List<Compatibility> compatibility) {
                this.compatibility = compatibility;
           }
           
           @CollectionOfElements
           public List<Danger> getDangers() {
                return dangers;
           }
           
           public void setDangers(List<Danger> dangers) {
                this.dangers = dangers;
           }
      
           @CollectionOfElements
           public List<Equipment> getEquipment() {
                return equipment;
           }
      
           public void setEquipment(List<Equipment> equipment) {
                this.equipment = equipment;
           }
      
           @NotNull
           public SamplingDevice getSamplingDevice() {
                return samplingDevice;
           }
      
           public void setSamplingDevice(SamplingDevice samplingDevice) {
                this.samplingDevice = samplingDevice;
           }
           
           @OneToMany(mappedBy="chemical", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
           public List<Translation> getTranslations() {
                return translations;
           }
      
           public void setTranslations(List<Translation> translations) {
                this.translations = translations;
           }
      
           @NotNull
           public TankType getTankType() {
                return tankType;
           }
      
           public void setTankType(TankType tankType) {
                this.tankType = tankType;
           }
      
           @NotNull
           public HullType getHullType() {
                return hullType;
           }
      
           public void setHullType(HullType hullType) {
                this.hullType = hullType;
           }
      
           public ExplosionGroup getExplosionGroup() {
                return explosionGroup;
           }
      
           public void setExplosionGroup(ExplosionGroup explosionGroup) {
                this.explosionGroup = explosionGroup;
           }
      
           @NotNull
           public Condition getTankCondition() {
                return tankCondition;
           }
      
           public void setTankCondition(Condition tankCondition) {
                this.tankCondition = tankCondition;
           }
      
           public TankEquipment getTankEquipment() {
                return tankEquipment;
           }
      
           public void setTankEquipment(TankEquipment tankEquipment) {
                this.tankEquipment = tankEquipment;
           }
      
           @Column(length=5000)
           public String getInternalNote() {
                return internalNote;
           }
      
           public void setInternalNote(String internalNote) {
                this.internalNote = internalNote;
           }
           
      }