1 Reply Latest reply on Apr 15, 2009 12:12 AM by gonorrhea

    caching dataTable values for history log

    gonorrhea

      So I need to insert a record into a FooChangeLog table.  One of the columns is the original value prior to update.  Any best practices on how to handle this in Seam/Hibernate, etc?


      I can keep a copy of the List that is outjected by @DataModel/@Factory pattern and just use that while I'm looping thru the entities in the list during the submit() method.  But not sure if that's the most Seam-esque or elegant way of handling this.


      ApplicationSettingsAction.java


      @Name("applicationSetting")
      @Stateful
      public class ApplicationSettingsAction implements ApplicationSettingsLocal {
      
           @In
           private EntityManager entityManager;
           
           @Logger
           private Log log;
           
           @DataModel
           private List<ApplicationSetting> applicationSettingData;
           
           //----------------------------------BEGIN METHODS--------------------------------------------//
           
           @Factory("applicationSettingData")
           public void getApplicationSettingData(){
                applicationSettingData = entityManager.createQuery("from ApplicationSetting")
                                                                .getResultList();
           }
      
           public void submit() {
                
                for (ApplicationSetting appSetting : applicationSettingData){
                     //update ApplicationSetting table
                     entityManager.merge(appSetting);
                     
                     //insert record(s) into ApplicationSettingChangeLog table...
      
      //imagine local variable declarations here... :)
      
                     ApplicationSettingChangeLog applicationSettingChangeLog = new ApplicationSettingChangeLog(employeeByAddedByEmployeeId, applicationSetting,                                                                                                                             employeeByUpdatedByEmployeeId,                                                                                                                             previousSettingValue, new Date(), new Date());
      
                     entityManager.persist(applicationSettingChangeLog);
                }
                
      
                
           }
           
           @Remove @Destroy
           public void destroy() {}
      
      }

        • 1. Re: caching dataTable values for history log
          gonorrhea

          here is an extremely complicated Hibernate audit solution: http://www.hibernate.org/318.html.  I also read about envers but not interested in anything too fancy for auditing only one table.


          anyways, I tried to clone the List and then use it for the change log logging (I don't know how/if I can access the original data in the List like we did in the Powerbuilder days with the datawindow buffers).  The issue I'm running into is that the values for the entities are the same for both List (original and clone) in the submit() method.  I think somehow the entities in the two Lists are being sync'd up.  I gave up figuring it out.


          Problem: the value that gets inserted into the change log table are the new values, not the old values.


          Can someone kindly point out what I'm missing in my code that's causing this to happen?


          .xhtml:


          <!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:ui="http://java.sun.com/jsf/facelets"
               xmlns:h="http://java.sun.com/jsf/html"
               xmlns:f="http://java.sun.com/jsf/core"
               xmlns:a4j="http://richfaces.org/a4j"
               xmlns:rich="http://richfaces.org/rich"
               xmlns:s="http://jboss.com/products/seam/taglib"
               template="/templates/normal.xhtml">
               
               <ui:define name="body">
               
                    <h3>Site Administration</h3>
                    <h:form id="form1">
                         <rich:dataTable value="#{applicationSettingDataList}" var="appSetting"> 
                                   
                              <rich:column>
                                   <f:facet name="header"><h:outputText value="ID"/></f:facet>                    
                                   <h:outputText value="#{appSetting.settingId}"/>
                              </rich:column>
                              <rich:column>
                                   <f:facet name="header"><h:outputText value="Setting Name"/></f:facet>                    
                                   <b><h:outputText value="#{appSetting.settingName}"/></b>
                                   <h:outputText value="#{appSetting.settingDescription}"/>
                              </rich:column>
                              <rich:column>
                                   <f:facet name="header"><h:outputText value="Setting Value"/></f:facet>                    
                                   <h:inputText value="#{appSetting.settingValue}"/>
                              </rich:column>
                         </rich:dataTable>
                         <h:commandButton value="Submit" action="#{applicationSetting.submit}"/>
                         <!-- <a4j:commandButton type="button" value="Cancel"/>  --> 
                    </h:form>
               
               </ui:define>     
          </ui:composition>



          backing bean:


          @Name("applicationSetting")
          @Stateful
          public class ApplicationSettingsAction implements ApplicationSettingsLocal {
          
               @In
               private EntityManager entityManager;
               
               @Logger
               private Log log;
               
               @DataModel
               private List<ApplicationSetting> applicationSettingDataList;
               
               private List<ApplicationSetting> applicationSettingDataOriginalList;
               
               private List<String> previousSettingValueList = new ArrayList<String>();
               
               //----------------------------------BEGIN METHODS--------------------------------------------//
               
               @Factory("applicationSettingDataList")
               @Begin(join=true)
               @SuppressWarnings("unchecked")
               public void getApplicationSettingData(){
                    applicationSettingDataList = entityManager.createQuery("from ApplicationSetting").getResultList();          
                    applicationSettingDataOriginalList = entityManager.createQuery("from ApplicationSetting").getResultList();
                              
                    /*for(int i = 0; i < applicationSettingDataList.size(); i++){
                         previousSettingValueList.add(applicationSettingDataList.get(i).getSettingValue());
                    }
                    */
                    log.info("in submit: before applicationSettingDataList"); 
                    
                    log.info("***********************************************************************"); 
                    
                    for(ApplicationSetting appSetting : applicationSettingDataList){
                         log.info("appSetting.getSettingId() = " + appSetting.getSettingId());
                         log.info("appSetting.getSettingName() = " + appSetting.getSettingName());
                         log.info("appSetting.getSettingValue() = " + appSetting.getSettingValue());
                    }
                    
                    log.info("in submit: before applicationSettingDataOriginalList");
                    
                    log.info("***********************************************************************");
                    
                    for(ApplicationSetting appSetting : applicationSettingDataOriginalList){
                         log.info("appSetting.getSettingId() = " + appSetting.getSettingId());
                         log.info("appSetting.getSettingName() = " + appSetting.getSettingName());
                         log.info("appSetting.getSettingValue() = " + appSetting.getSettingValue());
                    }
                    
          
               }
               
               //@End
               public void submit() {
                    
                    //testing
                    
                    log.info("in submit: before applicationSettingDataList"); 
                    
                    log.info("***********************************************************************"); 
                    
                    for(ApplicationSetting appSetting : applicationSettingDataList){
                         log.info("appSetting.getSettingId() = " + appSetting.getSettingId());
                         log.info("appSetting.getSettingName() = " + appSetting.getSettingName());
                         log.info("appSetting.getSettingValue() = " + appSetting.getSettingValue());
                    }
                    
                    log.info("in submit: before applicationSettingDataOriginalList");
                    
                    log.info("***********************************************************************");
                    
                    for(ApplicationSetting appSetting : applicationSettingDataOriginalList){
                         log.info("appSetting.getSettingId() = " + appSetting.getSettingId());
                         log.info("appSetting.getSettingName() = " + appSetting.getSettingName());
                         log.info("appSetting.getSettingValue() = " + appSetting.getSettingValue());
                    }
                    
                    //end testing
                    
                    Date today = new Date();
                    
                    for (int i = 0; i < applicationSettingDataList.size(); i++){
                    
                         //update ApplicationSetting table
                         entityManager.merge(applicationSettingDataList.get(i));
                         
                         //ntUsername needs to be populated by outjection from Authenticator... 
                         String ntUsername = "CORP\\asookazi";
                         
                         //where do we get the employeeId from?  possibly NotificationOfAbsence.dbo.Employee table.  hardcoding to 0 (admin) for now...
                         List<Employee> employeeList = entityManager.createQuery("from Employee e where e.ntusername = :ntUsername")
                                                                                 .setParameter("ntUsername", ntUsername)
                                                                                 .getResultList();
                         
                         Employee employee = employeeList.get(0);
                         
                         //insert record(s) into ApplicationSettingChangeLog table as required...
                         if (applicationSettingDataOriginalList.get(i).getSettingValue() != applicationSettingDataList.get(i).getSettingValue()){
                                   ApplicationSettingChangeLog applicationSettingChangeLog = new ApplicationSettingChangeLog(employee,
                                                                                                                                            applicationSettingDataOriginalList.get(i),
                                                                                                                                            employee,
                                                                                                                                            applicationSettingDataOriginalList.get(i).getSettingValue(), 
                                                                                                                                            today, 
                                                                                                                                            today);
                                   
                                   entityManager.persist(applicationSettingChangeLog);
                         }
                                        
                         
                    }
                    
          
                    
               }
               
               @Remove @Destroy
               public void destroy() {
                    log.info("in destroy()");
               }
          
          }