I have a Java Swing Application that use JPA 2 for database access. I need to add auditing features to the application (not using database triggers).

For example the customer object is retrieved and update the UI with the customer object values. When the user presses the Save button on the form, I would like to add an audit entry to the database with before and after values (change values only of course).

I don't know whether there are recognized "best practices" for this, but I have the same requirement.

I have a Java Swing Application that use JPA 2 for database access. I need to add auditing features to the application (not using database triggers).

Very same requirements indeed (hey maybe we're even colleagues! :o)

For example the customer object is retrieved and update the UI with the customer object values. When the user presses the Save button on the form, I would like to add an audit entry to the database with before and after values (change values only of course).

Is there any best practice design pattern for acheiving this?

As I said, I'm not aware of best practices for this, but my current thinking goes along this (multiple solutions, if anyone wishes to comment be my guest):
1) Let's start with the obvious: if we exclude DB-specific capabilities, let's put the logic in Java code
2) Specifically, the DAO layer seems like a good place: it's more appropriate to manage the transaction at this layer.
3) Within this layer, I am thinking about using either of:
3-a: - Observer (I prefere to use typed Listeners (not to be confused with GUI listeners), but I still consider this a derived idiom of the Observer pattern): when the audited entity is about to be saved, record its current state, save the new state, then notify observers/listeners about the change. The DAO has to have specific code, but the client code (presumably the service layer code which call the dao.save(...) method) is unaware of (not coupled to) the auditing.
3-b:- Decorator : wrap the base DAO into a decorator (same interface) that does the record/notify, leaving both the basic DAO and the client code unaware of the auditing
3-c: - Facade : similar approach, except that the client code knows about the Facade instead of the basic DAO interface, so in a way it knows that there is additional stuff going on (though not necessarily that this additional stuff is auditing

The trick is to manage the transactions. In my case I have to support different auditing implementations, so I tend to bend towards not including the audit in the transaction (I am discussing with the product owners which guarantees we have to provide as to "losing" audit entries if they are the responsibilities of an external system); if I can get away with not including the auditing in the transaction I'll be much more comfortable.

4) Note that there may be arguments to put this logic in the Service layer instead; in particular, the service layer may already have the current state of the entity (e.g. record the entity's state before presenting it to the edition UI), so that would save one DB round-trip.
However, that aspect (performance) doesn't matter much in a single-user, standalone, app. And if it does matter, one DB round-trip is unlikely to affect it (and if it does, there are solutions, such as caching, which is a good fit for a single-user, standalone app.
As I said, the service layer may be a more awkward place to manage transactions.
Moreover, it forces to explicitly know about (be coupled to) the auditing code.

5) Whatever the approach, there may be a trick to record the values before edition: you can put such logic in the Entity class itself, using @Transient attributes updated when calling the setters of the regular JPA-managed attributes.

6) Eventually, one solution that shields all code (DAO, service) from coupling to the auditing, is to inject decorators into the service layer. In particular, auditing may be a good case for using AOP (Aspect-Oriented Programming). It's indeed a specific implementation of suggestion 3-b

Looking forward to reading your comments and those of others,
Best regards,

jduprez wrote:
2) Specifically, the DAO layer seems like a good place: it's more appropriate to manage the transaction at this layer.

Analyze the business requirements first.

For example what specificallly do you want to collect in the follownig situations.
1. User is deleted (user which belongs to multiple roles.)
2. New customer is created.
3. Customer order is parked waiting on credit approval (think B2B rather than credit card.)
4. Must track who looked at the data (there is in fact a business domani where regulatory requirements require this.)

All of the above involve multiple tables, so in a DAO layer does that justify writing records for each table?
What exactly does one write for a change of any sort - is sufficient to note that it was changed or does one need a record of the change itself?
How exactly does one track a deletion?
What sort of reports are needed on this data?

Insure exactly what 'audit' means. All of the following are possible.
- Regulatory requirements might require an 'audit' record
- A manager might want an 'audit' of what the call center employees did.
- An external customer might want to keep a 'audit' of all changes.
- Developement might decide that it should keep an 'audit' of what the applications do. Myself I call this 'logging' or 'trace logging' although both of those terms can also end up referring to business needs rather than developement needs.

Verify the impact of putting the 'audit' in place. It might seem like a good idea to do it in a java app but only if there is no access to data except through the app. For instance if there is a nightly upload process is it acceptable to ignore that that process is the 'user' that created the data?