google-code-export / hibernate-audit

Automatically exported from code.google.com/p/hibernate-audit
2 stars 1 forks source link

null pointer exception on AuditListener.onPreRemoveCollection ::: but there is no update of any collection object, just plain update query #8

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
an entity with a collection, but not used , for insert or update

What is the expected output? What do you see instead?

What version of the product are you using? On what operating system?
Hibernate 3.6.7 final, Java 1.7

Please provide any additional information below.
1. Entity Attached
2. DAO method attached
3. Exception trace attached
--------------------------------------------------------------------------------
----------------------------
Hibernate:
    update
        S001_200300
    set
        S200300_0002=?,
        S200300_0501=?,
        S200300_0502=?,
        S200300_0503=?,
        S200300_0504=?,
        S200300_0515=?,
        S101000_0001=?
    where
        S200300_0001=?
DEBUG Segment.put 420 [127.0.0.1 - Java/1.7.0] - put added 0 on heap
DEBUG Segment.fault 774 [ - ] - fault removed 0 from heap
DEBUG Segment.fault 787 [ - ] - fault added 0 on disk
ERROR AuditListener.onPreRemoveCollection 367 [127.0.0.1 - Java/1.7.0] - 
RuntimeException occured during onPreRemoveCollection, will re-throw the 
exception
java.lang.NullPointerException: null
        at com.googlecode.hibernate.audit.synchronization.work.RemoveCollectionAuditWorkUnit.init(RemoveCollectionAuditWorkUnit.java:70) ~[hibernate-audit-1.0.34.jar:1.0.34]
        at com.googlecode.hibernate.audit.synchronization.AuditSynchronization.addWorkUnit(AuditSynchronization.java:65) ~[hibernate-audit-1.0.34.jar:1.0.34]
        at com.googlecode.hibernate.audit.listener.AuditListener.onPreRemoveCollection(AuditListener.java:363) ~[hibernate-audit-1.0.34.jar:1.0.34]
        at org.hibernate.action.CollectionRemoveAction.preRemove(CollectionRemoveAction.java:134) [hibernate3.jar:3.6.7.Final]
        at org.hibernate.action.CollectionRemoveAction.execute(CollectionRemoveAction.java:100) [hibernate3.jar:3.6.7.Final]
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) [hibernate3.jar:3.6.7.Final]
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) [hibernate3.jar:3.6.7.Final]
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:186) [hibernate3.jar:3.6.7.Final]
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) [hibernate3.jar:3.6.7.Final]
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) [hibernate3.jar:3.6.7.Final]
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) [hibernate3.jar:3.6.7.Final]
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) [hibernate3.jar:3.6.7.Final]
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) [hibernate3.jar:3.6.7.Final]
        at com.infosmart.synergies.dao.S001200300DAOImpl.saveFiscalYrHeader(S001200300DAOImpl.java:50) [S001200300DAOImpl.class:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0]
        at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0]
        at com.infosmart.synergies.LookupServlet.executeRequestedMethod(LookupServlet.java:205) [LookupServlet.class:na]
        at com.infosmart.synergies.LookupServlet.doGet(LookupServlet.java:97) [LookupServlet.class:na]
        at com.infosmart.synergies.LookupServlet.doPost(LookupServlet.java:175) [LookupServlet.class:na]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) [servlet-api.jar:na]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) [servlet-api.jar:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) [catalina.jar:7.0.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.11]
        at ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter(MDCInsertingServletFilter.java:51) [logback-classic-0.9.29.jar:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) [catalina.jar:7.0.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.11]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) [catalina.jar:7.0.11]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) [catalina.jar:7.0.11]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498) [catalina.jar:7.0.11]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) [catalina.jar:7.0.11]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) [catalina.jar:7.0.11]
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) [catalina.jar:7.0.11]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [catalina.jar:7.0.11]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394) [catalina.jar:7.0.11]
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243) [tomcat-coyote.jar:7.0.11]
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) [tomcat-coyote.jar:7.0.11]
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166) [tomcat-coyote.jar:7.0.11]
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) [tomcat-coyote.jar:7.0.11]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [na:1.7.0]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [na:1.7.0]
        at java.lang.Thread.run(Thread.java:722) [na:1.7.0]
DEBUG Segment.put 420 [127.0.0.1 - Java/1.7.0] - put added 0 on heap
DEBUG Segment.fault 774 [ - ] - fault removed 0 from heap
DEBUG Segment.fault 787 [ - ] - fault added 0 on disk
DEBUG S001200300DAOImpl.saveFiscalYrHeader 55 [127.0.0.1 - Java/1.7.0] - 
saveFiscalYear failed
java.lang.NullPointerException: null
        at com.googlecode.hibernate.audit.synchronization.work.RemoveCollectionAuditWorkUnit.init(RemoveCollectionAuditWorkUnit.java:70) ~[hibernate-audit-1.0.34.jar:1.0.34]
        at com.googlecode.hibernate.audit.synchronization.AuditSynchronization.addWorkUnit(AuditSynchronization.java:65) ~[hibernate-audit-1.0.34.jar:1.0.34]
        at com.googlecode.hibernate.audit.listener.AuditListener.onPreRemoveCollection(AuditListener.java:363) ~[hibernate-audit-1.0.34.jar:1.0.34]
        at org.hibernate.action.CollectionRemoveAction.preRemove(CollectionRemoveAction.java:134) ~[hibernate3.jar:3.6.7.Final]
        at org.hibernate.action.CollectionRemoveAction.execute(CollectionRemoveAction.java:100) ~[hibernate3.jar:3.6.7.Final]
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) ~[hibernate3.jar:3.6.7.Final]
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) ~[hibernate3.jar:3.6.7.Final]
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:186) ~[hibernate3.jar:3.6.7.Final]
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) ~[hibernate3.jar:3.6.7.Final]
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) ~[hibernate3.jar:3.6.7.Final]
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) ~[hibernate3.jar:3.6.7.Final]
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) ~[hibernate3.jar:3.6.7.Final]
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) ~[hibernate3.jar:3.6.7.Final]
        at com.infosmart.synergies.dao.S001200300DAOImpl.saveFiscalYrHeader(S001200300DAOImpl.java:50) ~[S001200300DAOImpl.class:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0]
        at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0]
        at com.infosmart.synergies.LookupServlet.executeRequestedMethod(LookupServlet.java:205) [LookupServlet.class:na]
        at com.infosmart.synergies.LookupServlet.doGet(LookupServlet.java:97) [LookupServlet.class:na]
        at com.infosmart.synergies.LookupServlet.doPost(LookupServlet.java:175) [LookupServlet.class:na]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) [servlet-api.jar:na]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) [servlet-api.jar:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) [catalina.jar:7.0.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.11]
        at ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter(MDCInsertingServletFilter.java:51) [logback-classic-0.9.29.jar:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) [catalina.jar:7.0.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.11]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) [catalina.jar:7.0.11]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) [catalina.jar:7.0.11]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498) [catalina.jar:7.0.11]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) [catalina.jar:7.0.11]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) [catalina.jar:7.0.11]
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) [catalina.jar:7.0.11]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [catalina.jar:7.0.11]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394) [catalina.jar:7.0.11]
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243) [tomcat-coyote.jar:7.0.11]
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) [tomcat-coyote.jar:7.0.11]
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166) [tomcat-coyote.jar:7.0.11]
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) [tomcat-coyote.jar:7.0.11]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [na:1.7.0]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [na:1.7.0]
        at java.lang.Thread.run(Thread.java:722) [na:1.7.0]

--------------------------------------------------------------------------------
-----------------------------------------------------------------------

    public Boolean saveFiscalYrHeader(S001200300 transientInstance) throws Exception
    {
    log.debug("saving S001200300 instance");
    Session session = null;
    Transaction begintransaction = null;
    try
    {
        session = getSession();
        begintransaction = session.beginTransaction();
        if (transientInstance.getS2003000001() != null && transientInstance.getS1010000001().equals(ServerConstants.MODIFIED))
        {
        transientInstance.setS2003000001(-1 * transientInstance.getS2003000001());
        transientInstance.setS2003000002(-1 * transientInstance.getS2003000002());
        }
            session.saveOrUpdate(transientInstance);
//      session.merge(transientInstance);
        //session.flush();
        begintransaction.commit();
        return true;
    }
    catch (Exception e)
    {
        log.debug("saveFiscalYear failed",e);
        begintransaction.rollback();
        throw e;
    }
    finally
    {
        if (session != null)
        {
        session.close();
        session = null;
        }
        if (begintransaction != null)
        {
        begintransaction = null;
        }
    }
    }

--------------------------------------------------------------------------------
-----------------------------------------------------------------------

package com.infosmart.synergies.entities;

import java.util.HashSet;
import java.util.Set;

import com.infosmart.synergies.dto.S001200300DTO;

/**
 * S001200300 entity. @author MyEclipse Persistence Tools
 */

public class S001200300 extends SynBaseEntity<S001200300DTO>
{

    private static final long serialVersionUID = 1L;
    // Fields

    private Long          s2003000001;
    private Long          s2003000002;
    private String      s2003000501;
    private String      s2003000502;
    private String      s2003000503;
    private String      s2003000504;
    private String      s2003000515;
    private Long          s1010000001;
    private Set<S001200310>   s001200310s      = new HashSet<S001200310>(0);

    // Constructors

    /** default constructor */
    public S001200300()
    {
    }

    /** minimal constructor */
    public S001200300(Long s2003000001, Long s2003000002, Long s1010000001)
    {
    this.s2003000001 = s2003000001;
    this.s2003000002 = s2003000002;
    this.s1010000001 = s1010000001;
    }

    /** full constructor */
    public S001200300(Long s2003000001, Long s2003000002, String s2003000501, String s2003000502, String s2003000503, String s2003000504, String s2003000515, Long s1010000001, Set<S001200310> s001200310s)
    {
    this.s2003000001 = s2003000001;
    this.s2003000002 = s2003000002;
    this.s2003000501 = s2003000501;
    this.s2003000502 = s2003000502;
    this.s2003000503 = s2003000503;
    this.s2003000504 = s2003000504;
    this.s2003000515 = s2003000515;
    this.s1010000001 = s1010000001;
    this.s001200310s = s001200310s;
    }

    public S001200300(Long s2003000001, Long s2003000002, String s2003000501, String s2003000502, Long s1010000001)
    {
    this.s2003000001 = s2003000001;
    this.s2003000002 = s2003000002;
    this.s2003000501 = s2003000501;
    this.s2003000502 = s2003000502;
    this.s1010000001 = s1010000001;
    }

    public S001200300(Long s2003000001, Long s2003000002, String s2003000501)
    {
    this.s2003000001 = s2003000001;
    this.s2003000002 = s2003000002;
    this.s2003000501 = s2003000501;
    }

    // Property accessors

    public Long getS2003000001()
    {
    return this.s2003000001;
    }

    public void setS2003000001(Long s2003000001)
    {
    this.s2003000001 = s2003000001;
    }

    public Long getS2003000002()
    {
    return this.s2003000002;
    }

    public void setS2003000002(Long s2003000002)
    {
    this.s2003000002 = s2003000002;
    }

    public String getS2003000501()
    {
    return this.s2003000501;
    }

    public void setS2003000501(String s2003000501)
    {
    this.s2003000501 = s2003000501;
    }

    public String getS2003000502()
    {
    return this.s2003000502;
    }

    public void setS2003000502(String s2003000502)
    {
    this.s2003000502 = s2003000502;
    }

    public String getS2003000503()
    {
    return this.s2003000503;
    }

    public void setS2003000503(String s2003000503)
    {
    this.s2003000503 = s2003000503;
    }

    public String getS2003000504()
    {
    return this.s2003000504;
    }

    public void setS2003000504(String s2003000504)
    {
    this.s2003000504 = s2003000504;
    }

    public String getS2003000515()
    {
    return this.s2003000515;
    }

    public void setS2003000515(String s2003000515)
    {
    this.s2003000515 = s2003000515;
    }

    public Long getS1010000001()
    {
    return this.s1010000001;
    }

    public void setS1010000001(Long s1010000001)
    {
    this.s1010000001 = s1010000001;
    }

    public Set<S001200310> getS001200310s()
    {
    return this.s001200310s;
    }

    public void setS001200310s(Set<S001200310> s001200310s)
    {
    this.s001200310s = s001200310s;
    }

}

--------------------------------------------------------------------------------
-----------------------------------------------------------------------

Original issue reported on code.google.com by Mr.Sony....@gmail.com on 6 Dec 2011 at 9:38

GoogleCodeExporter commented 9 years ago
It seems that you are trying to replace a collection property of an entity that 
did not have that property loaded. At least this seems to be the case when 
PreCollectionRemoveEvent event is thrown from hibernate and its collection 
property is null. Although it is a valid Hibernate case (e.g. replace the 
collection even when the collection was not loaded) from hibernate audit 
perspective we have to know at least the collection property name in order to 
record anything. The property name for the collection is obtained from the 
collection persister and this is not provided directly from the 
PreCollectionRemoveEvent neither the collection role (which holds also what is 
the property name) - hence the only way we can obtain that information is to 
get the collection persister from the session by passing the persistence 
collection - which in this case is null and because of that it throws NPE. Now 
we have either to get that information (role name/property name - as minimum) 
or we have to ignore the event when the collection is null which is also not a 
very good thing. Now if Hibernate changes the PreCollectionRemoveEvent and 
PostCollectionRemoveEvent to include the collection persister or the collection 
role then we can do more stuff when the collection inside the event is null (I 
do not know if someone asked and created a JIRA for Hibernate to add that in 
the event nor if they are going to do that change in the near future) 

As a work around I would suggest to not replace the whole collection when the 
collection was not loaded from the database if this is possible. 

I have to think about this problem and if we can go around those obstacles that 
I've mentioned without any Hibernate changes and to not miss events.

For now I will leave this issue open.

Original comment by kchobant...@gmail.com on 8 Dec 2011 at 5:20

GoogleCodeExporter commented 9 years ago
I have created a new Hibernate JIRA for accessing the collection persister even 
when the collection was not loaded/new/or null

https://hibernate.onjira.com/browse/HHH-6882

Original comment by kchobant...@gmail.com on 8 Dec 2011 at 6:03