[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [aspectj-users] How to advise setters in JPA entities using AOP?
|
I have tried to answer that under http://stackoverflow.com/a/24839202/1082681 if anyone is interested.
Bottom line: set() pointcuts are not enough here, you need to do manual bookkeeping for which collections/maps are assigned to which object members of interest. I think my solution is rather ugly, but it was fun to develop. Hopefully someone else can come up with something better.
--
Alexander Kriegisch
http://scrum-master.de
Eric B schrieb am 16.07.2014 18:51:
> I've posted this question on StackOverflow (http://stackoverflow.com/q/24786391/827480 <http://stackoverflow.com/q/24786391/827480> ), but am sending it here as well as not everyone monitors StackOverflow.
>
>
> have the need to log any changes to fields in an entity - whether it is a String change, or addition/deletion to a collection/map.
>
> Given a JPA entity with a bunch of primitive fields, it is fairly trivial to write an pointcut that will intercept any set(..) methods on the fields.
>
> However, where I am stuck is how to write the pointcut to handle Collections/Sets/Embedded/etc.
>
> Given the following entity:
>
>
> @Entity
> public class Provider implements Serializable {
>
> @Id
> @GeneratedValue(strategy = GenerationType.AUTO)
> @Column(name = "id")
> private Long id;
>
>
> private String name;
>
> @Column(name="type", nullable=false)
> @Enumerated(EnumType.STRING)
> private ProviderType providerType;
>
>
> @ManyToMany
> private List<Contact> contacts;
>
> @Embedded
> private Validity validity;
>
> // setters and getters omitted for brevity
>
> }
>
>
> where Contact is a simple entity with a bunch of primitive fields and Validity is a non-entity object with some primitive fields.
>
> The following pointcut will intercept all set() methods in the class:
>
>
> pointcut fieldSetter() : set(!static !final !transient * *.Provider) && args(val) && target(o);
>
>
> to which I can write a before/after/around advice.
>
>
> before( Object val, Object o) : fieldSetter{
> String fieldName = thisJoinPointStaticPart.getSignature().getName();
> System.out.println( "Object being changed: " + o.toString() );
> System.out.println( "New Value for: " + fieldname + " is: " + v.toString() );
> }
>
>
> But how do I handle that case for an Embedded object or a Collection? For an Embedded object, if I just put my advice around the setter method in the object, how do I know which is the parent object that is actually being modified/persisted?
>
> And in the case of collections/sets/maps/etc, how do I advise against the add/remove methods? What I need to end up doing is advising the getCollection().add() methods as well as the getCollection.remove() methods. But I can't seem to figure out a good way.
>
>
> Thanks,
>
> Eric
>
>