2 Replies Latest reply on Jun 27, 2013 1:20 PM by Tom Lerma

    Cannot audit subclass of non-audited "JOINED" superclass

    Tom Lerma Newbie

      I have a problem with trying to get a class to audit using Envers 4.1.10.  Here is the situation as best as I can describe it.  I am using a framework called broadleaf that defines a super class (SkuImpl.class) which I inherit from.  This class is defined as an entity class with a superclass inheritance type of joined.  It is in a library and cannot be modified.  This class is defined as follows (notice that it is not audited and notice the "JOINED" inheritance type):

       

      @Entity

      @Inheritance(strategy = InheritanceType.JOINED)

      @Table(name = "BLC_SKU")

      @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "blStandardElements")

      @AdminPresentationClass(friendlyName = "baseSku")

      public class SkuImpl implements Sku { ....

       

      Then I have my class which extends the super class (MySkuImpl.class) which is defined as below:

       

      @Audited

      @AuditOverride(forClass=SkuImpl.class, isAudited=true)

      @Entity

      @Table(name = "MY_SKU")

      public class MySkuImpl extends SkuImpl implements Sku { ...

       

      When I run this, I get the following error:

       

            org.hibernate.MappingException: Entity 'com.....MySkuImpl' is audited, but its superclass: 'org...SkuImpl' is not.

       

      I believe the @AuditOverride may not be working because the superclass is a JOINED superclass and not a mappedSuperclass.  I had also tried the deprecated method of using:  @Audited(auditParents = {SkuImpl.class}), however, that didn't work either and yielded the same error message as shown above.  I also tried using orm.xml to turn SkuImpl into a mappedsuperclass, however, this breaks references to the SkuImpl that are elsewhere in the code.  So at this point, I'm not sure of what options remain to get this working.  If anyone has any advice or suggestions on how to tackle this problem, I would really appreciate it.  Thanks.

        • 1. Re: Cannot audit subclass of non-audited "JOINED" superclass
          Adam Warski Master

          You would have to get the superclass audited somehow. Currently there's no other way to specify such metadata except for annotations.

           

          Adam

          • 2. Re: Cannot audit subclass of non-audited "JOINED" superclass
            Tom Lerma Newbie

            Thanks for the feedback Adam, I discovered that you were right and found that in order to accomplish this I needed to do some work to inject those annotations into the parent class at run-time.  I'm using Broadleaf, which provides some class transforming interfaces where I was able to do the below, which adds class level parameter "@Audited" at run-time to the parent class:

             

            ClassPool classPool = ClassPool.getDefault();

                                                    CtClass clazz = classPool.makeClass(new ByteArrayInputStream(

                                                                        classfileBuffer), false);

                                                    clazz.defrost();

             

                                                    ClassFile classFile = clazz.getClassFile();

                                                    ConstPool constPool = classFile.getConstPool();

                                      

                                                    classFile.getAttributes().get(1);

                                                    AnnotationsAttribute attr = (AnnotationsAttribute) classFile.getAttributes().get(1);

                                                    Annotation auditAnnotation = new Annotation("org.hibernate.envers.Audited", constPool);

                                                    attr.addAnnotation(auditAnnotation);

                                                    classFile.addAttribute(attr);

             

                                                    classPool.importPackage("org.hibernate.envers.RelationTargetAuditMode");

             

                                                    return clazz.toBytecode();

             

             

            Then broadleaf provided some other transformers that basically copy annotations from one template class to a class that is in a lib(jar) file, which I was able to use to control the field level annotations for auditing the parent super-class that is stored away in the jar file.  This all happens during run-time initialization, and is currently working.  Not the most straight-forward way but it works.