Hi Adam,
Currently, the ways to enable auditing on a mapped-superclass that we discussed below do
not work when an embeddable class has no declared data. The only way I can find to enable
auditing for the mapped-superclass is to annotate the embeddable class with @Audited.
For example:
@Entity
@Audited
public class A{
...
private B b;
...
}
@Embeddable
@Audited // currently, this must be here in order for the mapped-superclass to be audited
public class B extends AbstractB {
// no declared data
}
@MappedSuperclass
@Audited // does nothing due to HHH-9193, but will be required after
// HHH-9193 is fixed, unless there is an @AuditOverride
public class AbstractB {
private String strValue;
}
Annotating the embeddable class makes it work, but does this really make sense? Is this a
reasonable workaround? Could this cause problems in future versions?
The test case attached to HHH-8908 illustrates this.
Thanks,
Gail
----- Original Message -----
From: "Adam Warski" <adam(a)warski.org>
To: "Gail Badner" <gbadner(a)redhat.com>
Cc: adam(a)hibernate.org, "Hibernate" <hibernate-dev(a)lists.jboss.org>,
"Łukasz Antoniak" <lukasz.antoniak(a)gmail.com>
Sent: Tuesday, May 20, 2014 9:45:28 PM
Subject: Re: Envers: Mapped-superclasses extended by embeddabables
Sorry, no idea why I missed that email.
So the basic rule is:
- fields from a non-audited mapped superclass are never audited, unless an
@AuditOverride is specified
- if the mapped superclass is audited, then its fields are of course audited
as well
I don’t think we want to get into supporting a @AuditOverride(“b.field”)
syntax, as it complicates the whole thing. When an @AO is placed on a
component, the names refer to what is inside the component, so I guess we
can use it here?
To address the specific questions:
> In the following, A.b.intValue should be audited; A.b.strValue should not
> be audited.
>
> @Entity
> @Audited
> public class A{
> ...
> private B b;
> ...
> }
>
> @Embeddable
> public class B extends AbstractB {
> private int intValue;
> }
>
> @MappedSuperclass
> public class AbstractB {
> private String strValue;
> }
Looks good
> In the following, both A.b.intValue and A.b.strValue should be audited:
>
> @Entity
> @Audited
> @AuditOverride( name="b.strValue" )
> public class A{
> ...
> private B b;
> ...
> }
>
> @Embeddable
> public class B extends AbstractB {
> private int intValue;
> }
>
> @MappedSuperclass
> public class AbstractB {
> private String strValue;
> }
As above, I don’t think we want to supoprt @AO(name=“b.strValue”)? To audit
b.strValue, you’d have to add an @AO(name=“strValue”,
forClass=AbstractB.class) on the b field directly.
> In the following, both A.b.intValue and A.b.strValue should be audited:
>
> @Entity
> @Audited
> public class A{
> ...
> private B b;
> ...
> }
>
> @Embeddable
> public class B extends AbstractB {
> private int intValue;
> }
>
> @MappedSuperclass
> @Audited
> public class AbstractB {
> private String strValue;
> }
Yes
> In the following, both A.b.intValue and A.b.strValue should be audited.
>
> @Entity
> @Audited
> public class A{
> ...
> private B b;
> ...
> }
>
> @Embeddable
> @AuditOverride( class=AbstractB.class )
> public class B extends AbstractB {
> private int intValue;
> }
>
> @MappedSuperclass
> public class AbstractB {
> private String strValue;
> }
Yes
> What should be the outcome of the following? Should A.b.strValue still be
> audited even though A.b is explicitly not audited?
>
> @Entity
> @Audited
> public class A{
> ...
> @NotAudited
> private B b;
> ...
> }
>
> @Embeddable
> public class B extends AbstractB {
> private int intValue;
> }
>
> @MappedSuperclass
> @Audited
> public class AbstractB {
> private String strValue;
> }
@NotAudited has precedence - so not audited.
I hope things are a bit clearer :). I suppose we should document these rules.
If, of course, you think these rules are sound - any other ideas are always
welcome :)
Adam
--
Adam Warski
http://twitter.com/#!/adamwarski
http://www.softwaremill.com
http://www.warski.org