Saturday, May 22, 2010

All you need to know about java annotations - brief

1) What are annotations?

Annotations are tags (@) that you insert into your source code which acts as information to an external tool that process them.
Example:

@Log(logLevel="Debug")
public void someAPI(){...}


@Log is an annotation here which informs the external tool which processes @Log to start logging in debug mode when someAPI method is executed.

2) Why do we need Annotations?

Some of the uses of annotations could be
#) Provide information to the tools so that the tools can generate auxiliary files such as deployment descriptors.
#) Provide information to the tools so that the tools can automatically generate code for testing, logging, transaction, security etc.


3) How of Annotations?

#) Defining Annotations -
Considering the above log example, this is how @Log can be defined

import java.lang.annotations.*;

@Target (ElementType.METHOD)
@Retention (RetentionPolicy.RUNTIME)
public @interface Log
{
String logLevel() default "info";
}

The @Target and @Retention are annotations provided to another annotations and hence called meta annotations.

@Target annotation helps in specifying the target element on which @Log annotation can be used. In this example the METHOD is used as the target which indicates that @Log is applicable to only methods in a class.

You can add annotations to the following items
# Packages
# Classes (including enums)
# Interfaces (including annotation interfaces)
# Methods
# Constructors
# Instance Fields
# Local Variables
# Parameter Variables

Example: -

public @interface BugReport
{
enum Status {FIXED, NOTABUG};
boolean showStopper() default false;
String assignedTo() default "[None]";
Status status() default Status.UNCONFIRMED;
Reference ref() default @reference;
String[] reportedBy();
Class testCase() default Void.class
}


and annotation looks like this


@BugReport(showStoppre=true, assignedTo="xyz", testCase=TestClass.class,
status=BugReport.Status.CONFIRMED, ...)


@Retention meta annotation specifies how long an annotation is retained. You can specify atmost one of the following values.

SOURCE - Annotatoins are not included in class file.
CLASS - Annotations are included in class file, but the virtual machine need not load them.
RUNTIME - Annotations are included in class file and loaded by the virtual machine. They are available throu the refelection API.

4) Annotation Processing

Annotation can be processed at three levels
#) In the source code [SOURCE]
You process annotation at the source level if you want to produce other source files, such as XML descriptor files, stubs/skeletons, remote interfaces etc. For source level annotations u need to parse java source file. Java provides an annotation process tool (apt) which processes annotations in source files and feeds them to annotation processor that you supply.

#) In bytecode files [CLASS]
If you want to process annotations at the bytecode level then you need to analyze class files. BCEL is the library which helps in processing class files and modifying class files. This type of processing can be used to modify class files to add byte codes for logging etc.
You can run a bytecode engineering tool in two modes.You can simply write a tool that
reads a class file, processes the annotations, injects the bytecodes, and writes the modified class file. Alternatively, you can defer the bytecode engineering until load time, when the class loader loads the class.

#) At Runtime, in the virtual machine [RUNTIME]
This is the easiest way of processing an annotation which can be done by reflection api's at runtime.

Saturday, March 13, 2010

Two Entities to One Table mapping

The picture below shows how two entities can be mapped to one single table -


Two Tables to One Entity mapping

The picture below shows how two table can be mapped to one single entity -

Entity Relationship Cascade

The table below shows the Entity Manager API used for cascading when you want to save entity relationship

Friday, March 12, 2010

Entity Manager Merge() Vs Persist()

Like every one knows Persist is used to create a new entry and merge is normally used to update an already existing entry but the confusion begins when we realize that merge can also be used to create a new entry as well.

So the question is why do we have persist when merge can do both update and create entries?

Here it goes -

1) Performance and Memory
Persist will just dump the entity into the database but merge will have to first figure out if this entry exists in the database for it to make out if it is a create or a update scenario. Secondly merge will copy the passed object and will save the copied object into the database, so if the entity relationship is complex this copy procedure is more time consuming and a lil memory intensive.

2) RBAC
Some roles can only update few entries and may not be allowed to create new entries or viceversa, so to have a seggregation we have seperate apis for persist and merge.

Sunday, February 28, 2010

Flush, Persist and Merge

Flush

There are two flush modes -
1) Auto
2) Commit

Auto flush is the default which flushes [persists] the entities in the persistence context at the transaction commit time and also on every query executed with in a transaction. Exception to this is find() because if we want to find an entity which is modified then the find will return back the entity that is present in the persistence context. But if we execute a query then query doesnt return the whole entity but returns some fields as a list and this is the reason that thepersistence context is flushed during query execution.

Commit mode will flush the persistence context when the transaction commits.

We can force flush by calling the flush method on the entity manager to flush the persistence context.


Persist and Merge

Merge can persist but persist cannot merge.
When an entity is persisted and before even the transaction is not commited, we can get the primary key if the primary key is autogenerated using table strategy.

Persistence Context and Entity Manager

Persistence Context is nothing but a bag that holds entities. Entity Manager contains persistence context and manages [creates, updates, deletes] the entities that are part of that persistence context. This is shown in the following figure


The life cycle of persistence context depends on whether it is transaction-scoped or extended persistence context.

Transaction-Scoped Persistence Context -

Transaction begins when the bean method is invoked and it ends when the method returns or completes. Similarly transaction-scoped persistence context follows the transaction and is created when the transaction begins and ends after the transaction commits or rolls back.



Extended Persistence Context -

This type of Persistence Context is independent of transaction i.e., the creation or destruction of persistence context is not dependent on transaction begin or transaction end as in the case of transaction-scoped persistence context. Persistence Context will be created when the statefull session bean is created and it is destroyed when the stateful session bean is destroyed.



Note:

There can be many instances of Entity Manager referring to the same single instance of persistence context if all these entity managers are part of the same transaction i.e., entity manager instances part of different ejb's invoked by an ejb which starts and ends the transaction. Please refer the picture below -