-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: OldValues argument NULL in onFlushDirty
PostPosted: Mon Mar 21, 2005 4:43 pm 
Regular
Regular

Joined: Tue Nov 09, 2004 5:15 pm
Posts: 100
I'm trying to implement history interceptor based on the implementation provided on the wiki page. I'm using hibernate 2.1.x.

My HistoryInterceptor's OnFlushDirty method when called has the oldValues set to NULL.

Here's my HibernateInterceptor's OnflushDirty method impl.


Code:

   public boolean onFlushDirty(Object obj, Serializable id, Object[] newValues, Object[] oldValues, String[] properties, Type[] types) throws CallbackException {

          if (!(obj instanceof Historizable)) {
            return false;
          }
          Historizable h = (Historizable) obj;
         
          // get the copy from the map
          Set entries = (Set) histories.get(obj);
          for (int i = 0; i < properties.length; i++) {
            // Skip the historyEntries
            if (properties[i].equals("historyEntries") == true) {
              continue;
            }
            Object oldOne = oldValues[i];
            Object newOne = newValues[i];
            // Check for changes
            if (oldOne == null && newOne == null) {
              continue;
            }
            if (newOne instanceof PersistentCollection) {
              // Collections must be compared against the snapshot
              PersistentCollection collection = (PersistentCollection) newValues[i];
              if (collection.isDirectlyAccessible() == false) {
                continue;
              }
              // retrieve Snapshot
              oldOne = collection.getCollectionSnapshot().getSnapshot();
              if (oldOne instanceof Map && newOne instanceof Set) {
                // a Set is internally stored as Map
                oldOne = ((Map) oldOne).values();
              }
            }
            if (oldOne != null && oldOne.equals(newOne) == true) {
              continue;
            }
            // Generate a new entry

            HistoryEntry entry = new HistoryEntry();
            entry.setWho(getUser());
            entry.setTimestamp(new Timestamp(new Date().getTime()));
            entry.setWhat("update");
            entry.setProperty(properties[i]);
            entry.setOldValue(format(oldOne));
            entry.setNewValue(format(newOne));
            if (log.isDebugEnabled()) {
              log.debug("Changed " + properties[i] + " from " + oldOne + " to " + newOne);
            }
            // and store it.
            entries.add(entry);
          }         
      return false;
   }




Here's my JUnit test case for HistoryInterceptor:

Code:

public void testHistoryInterceptor() throws Exception {

      Project project = new Project(); 
      project.setName("Espresso-New");   
      project.setStatus("New");
      
       dao.saveProject(project);   
      assertTrue("primary key assigned", project.getId() != null);   
      log.info(project);   
      assertEquals(1, project.getHistoryEntries().size());
      
      project = dao.loadProject(project.getId());
       Set hist = project.getHistoryEntries();
       assertEquals(1, hist.size());
       project.setStatus("New-1");
       dao.saveProject(project);
       assertEquals(2, project.getHistoryEntries().size());

/*
       project = dao.getProject(project.getId());
       hist = project.getHistoryEntries();
       log.debug("hist=" + hist);
       // Contains the creation and the modification
       assertEquals(2, hist.size());
       dao.removeProject(project.getId());
       */
   }



The first saveProject goes fine. When i do the update, i'm getting following NULL Pointer Exception as oldValues argument to OnFlushDirty is NULL.

Code:

  [junit] Testcase: testHistoryInterceptor(com.apple.ermt.persistence.audit.interceptor.HistoryInterceptorTest):      Caused an ERROR
    [junit] null
    [junit] java.lang.NullPointerException
    [junit]     at com.apple.ermt.persistence.audit.interceptor.HistoryInterceptor.onFlushDirty(HistoryInterceptor.java:113)
    [junit]     at net.sf.hibernate.impl.SessionImpl.flushEntity(SessionImpl.java:2535)
    [junit]     at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2454)
    [junit]     at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2256)
    [junit]     at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2235)
    [junit]     at org.springframework.orm.hibernate.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:214)
    [junit]     at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:201)
    [junit]     at org.springframework.orm.hibernate.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:341)
    [junit]     at com.apple.ermt.dao.hibernate.HibernateProjectDAO.saveProject(HibernateProjectDAO.java:47)
    [junit]     at com.apple.ermt.persistence.audit.interceptor.HistoryInterceptorTest.testHistoryInterceptor(HistoryInterceptorTest.java:36)
    [junit]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [junit]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    [junit]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)




Could someone please let me know why the oldValues is NULL for OnFlushDirty method?


Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 23, 2005 1:45 am 
Regular
Regular

Joined: Tue Nov 09, 2004 5:15 pm
Posts: 100
Could someone please let me know what's that i'm doing wrong???

I'm using session.saveOrUpdate to do the update and select-before-update is true but still the oldValues[] is NULL.

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 04, 2005 1:53 pm 
Newbie

Joined: Thu Mar 03, 2005 1:52 pm
Posts: 5
When you load the "project" in your dao.loadProject(id), are you using the same Hibernate Session when you call dao.saveProject(project)?

I believe they should be in the same HibernateSession in order for the previousValues[] to be populated.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.