niedziela, 28 października 2012

EJB 3.1 [6]

Entity callbacks and listeners

You can define callback for entity lifecycle events in two ways:
1. In entity class you define no-arg, void, checkedExceptionless method and annotate it with one of:
@[Pre/Post][Persist/Update/Remove] or @PostLoad.
2. You define this method in another class (MyFancyListener), except this time it would take and Object argument (representing the entity). The class needs a public, no-arg constructor. Next, you apply listener on entity by @EntityListeners annotation:


In the mapping xml you can define default listeners for all entities:


Then, you can exlude them for a specific entity with @ExcludeDefaultListeners.
Entity inherits parent entity interceptors, but those can also be excluded with @ExcludeSuperclassListeners.

Listeners execute from outside - first default ones, then parent and then those defined for an entity itself.


Security

While creating InitialContext to connect to EJB, you can pass properties containing username (Context.SECURITY_PRINCIPAL) and password (Context.SECURITY_CREDENTIALS).
You can use annotations like @RolesAllowed({"EMPLOYEE"}) and @PermitAll on methods.
Roles are defined either in deployment descriptor () or on the bean (@javax.annotation.security.DeclareRoles({"EMPLOYEE", "CLIENT"))).
Access can be restricted programatically by EJBContext methods getCallerPrincipal() and isCallerInRole().
There is also @RunAs annotation. It can be useful e.g. when MDB needs to access restricted method. (There is no user in context for MDBs).


JNDI and ENC

Beginning with eversion 3.1, all stateless and statefull beans have to be available in global JNDI context under name( elements in '[]' are optional):
java:global[/appOrEARName]/JARorWARName/beanName [!fullInterfaceName]
Example:


Beans have EnterpriseNamingContext. It's something like a map with references to other beans and resources. Before looking up a bean, you need to register it in current bean ENC (to register more EJBs use @EJBs annotation):

and then feel free to grab it:

Notice that when using ejbContext (as opposed to InitialContext) you can omit "java:comp/env" part of JNDI name.
You don't have to register anything if you use @EJB annotation directly on a field or it's setter - the ENC will get populated automatically.
If you specify name attribute of @EJB, the reference will be bound under this name. Otherwise, the name defaults to fullBeanName/fieldName.
Knowing this name, you can override it in xml, like this:

Other than name, @EJB has also mappedName and lookup attributes. MappedName is JNDI name used by provider. Lookup is the same (just vendor independent) - it came with the JNDI name standarization in version 3.1.

EJB name (name attribute of @Statefull/@Stateless or <ejb-name> in xml) has to be unique in EJB-JAR. In EARs there can be duplicates - if this is the case, use #:

Same applies to @PersistenceUnit injection:


When we use @EJB annotation without both mappedName and lookup, the container will:
- Look for an EJB with matching interface in EJB-JAR. if it finds more than one, a deployment exception will be thrown.
- Search other EJB-JARs.
- Search other global EJB-JAR deployments.

Other than EJBs, you can register resources in ENC:

Resources that are Strings or primitives are treated as environmental entries.

Brak komentarzy:

Prześlij komentarz