2 Replies Latest reply on Jan 14, 2013 7:31 PM by xevven

    Do Hibernate Filters work with Envers?

    xevven

      Hi All,

       

      I have several related (1-to-many) entities where one entity on the many side has a date attribute (like month or year; see below).

      The business case requires to load the object graph not completely (large amount of objects on the many side) but to load entity relations for a specific date range (e.g. load only those entities on the many side which belongs to a specific year).

      Standard JPA is not able to do this but Hibernate filters (http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#objectstate-filters) do the job quite well.

      As I also have the requirement to compare actual data with historic data and as I already use Envers for auditing the related entities I tried to use the filters together with Envers in order to load the audited object graph with the same filter but it seems Envers simply ignores the filter.

      I couldn't find any hint whether this should work or not so I don't know whether I'm doing something wrong or not.

      If this cobination does not work, is there any other way in Envers to achieve this partial loading of relationships?

       

      @Entity

      @Audited

      public class Foo implements Serializable {

           // ... skipped code

           @OneToMany

           Map<Long, Bar> bars;

      }

       

      @Entity

      @Audited

      @FilterDef(name="myfilter",

          parameters={

              @ParamDef( name="startYear", type="integer" ),

              @ParamDef( name="endYear", type="integer" )

              })

      public class Bar implements Serializable {

           // ... skipped code

           @OneToMany

           @Filter(name="myfilter",

                condition="year >= :startYear and year <= :endYear")

           Map<Long, YearData> years;

      }

       

      @Entity

      @Audited

      public class YearData implements Serializable {

           // ... skipped code

           private Integer year;

      }

       

       

      Here's what I tried:

       

      HibernateEntityManager hem = jpaEntityManager.unwrap(HibernateEntityManager.class);

      Session session = hem.getSession();

      org.hibernate.Filter filter = session.enableFilter("myfilter");

      filter.setParameter("startYear", 2010);

      filter.setParameter("endYear", 2012);   

      AuditReader aud = AuditReaderFactory.get(session);

      AuditQuery aq = aud.createQuery().forEntitiesAtRevision(Foo.class, revisionId)

              .add(AuditEntity.id().eq(entityId));

      Foo foo = (Foo) aq.getSingleResult();

      // pseudocode to run through all relationships in the graph to force Envers to load all relations

      foo.forceEagerLoading();

      session.disableFilter("PatternObject.weekfilter");

       

      The same filter works fine for my TypedQueries on actual data but the results clearly show that in case of the AuditQuery the filter is simply ignored and all YearData objects are loaded instead of just the ones defined by the filter.

       

      Any help would be appreciated.