Java Reference
In-Depth Information
bytecode of the class (unlike source retained annotations). If the JPA container, JPA
provider, EJB container, Spring, or anyone else, looks at the raw class bytes to deter-
mine which classes need to be managed, then the annotations can be found easily.
This is a common way to locate annotated classes, and so most containers will locate
your annotated classes, even if you don't import the annotation package. Up to this
point there isn't a problem; annotated classes will be found correctly, the problem is
with what happens next...
Having identified an annotated class for processing, it's common practice to load
it, and then use the Java reflection API to find the rest of the annotations present on
the class. There are two main reasons for this. First, it's much easier to use the reflec-
tion API than bytecode scanning to find all the annotations on a given class, and the
annotations are returned in a more easily used form. Second, by loading the class it's
much easier to find any annotations it has inherited from its type hierarchy. Those of
you who are particularly on the ball may now have noticed the problem. If the type is
loaded but the annotation package isn't available, then none of the annotations will
be visible! If you're lucky, this will cause an immediate failure, but usually containers
have sensible defaults for cases where there are no annotations. This can lead to part-
configured objects being used by the container, almost always with spectacularly
unpleasant results.
javax.persistence isn't the only package that can potentially cause this problem,
and because some packages contain only annotations, it's entirely possible that you
might run into this problem elsewhere. If you do use annotations, then consider using
a manifest generation/validation tool like bnd to make sure that you don't acciden-
tally end up in this situation.
JPA CLIENTS IN OSGI
Building a working manifest for a persistence bundle isn't a particularly difficult task,
but this is only part of the story. The other difference between OSG i and Java SE is the
way in which clients obtain an EntityManagerFactory . Unfortunately, this often
requires changes to the client code. In Java SE , the API for obtaining an EntityManager-
Factory is the Persistence bootstrap class, as follows:
Persistence.createEntityManagerFactory("myPUnit");
This model has a number of problems in OSG i. We've already mentioned the visibility
of the persistence descriptor, but there are also general problems with static factories
in OSG i that we'll discuss further in section 12.3.1. To avoid these problems in OSG i,
the JPA runtime registers the EntityManagerFactory as a service in the Service Regis-
try. After a client has looked up this service, it can use it in the same way that it did
before. In the case where there are multiple persistence units defined in the system,
then clients can filter on the persistence unit's name using the osgi.unit.name ser-
vice property.
This code change may seem like a big problem, but it's almost never pervasive.
Because EntityManagerFactory objects are designed to be created once and reused,
Search WWH ::




Custom Search