Java Reference
In-Depth Information
Why should the persistence unit and the entities be kept together? A persistence unit
and its entities are intimately related; one without the other doesn't give a complete
picture. In combination, the persistence unit defines not only the database backing
the entity classes, but also the way in which the entity classes are mapped into tables
within the database. This is a tight coupling, and so the artifacts should live in the
same bundle; making a change to an entity without reference to the persistence unit is
usually disastrous, which is why storing them independently is a bad idea. Not only is
keeping the persistence unit and its entity classes together wise, it's required by the
JPA Service Specification. If the entities are separated from the persistence unit, fea-
tures like runtime entity enhancement will stop working.
Having a discrete persistence bundle has a second advantage. If the persistence code
and domain model aren't tangled in with application business logic, the same persis-
tence services may be reused by several different applications. Having multiple persis-
tence units talking to the same database is far less efficient in terms of implementation
and maintenance effort. If either the implementation or the maintenance goes wrong,
there's the possibility of inaccurate entity mappings causing data corruption.
Packaging all of an application's entities together may not feel like the most natu-
ral pattern to you. If your database is complex, your persistence bundle might be quite
large, or even—say it isn't so—monolithic. Ultimately, your persistence bundle will
have the same modularity characteristics as your backing database. If the tables in
your database split nicely into separate groups with the entities representing them
having no mapped relationship (that is, they can be put into separate persistence
units), then those persistence units can be happily packaged in different persistence
bundles. On the other hand, if your entities are all interconnected, then they need to
be in a single persistence unit, and therefore a single persistence bundle. When you
think about it, this is exactly what you should be doing with classes in a bundle anyway.
Luckily, just because all of your entity classes are in a single bundle doesn't mean
they all have to be exposed to the rest of your application. Large domain models
should at least be divided across multiple packages. Consuming bundles should only
import the packages they need for their part of the business logic.
You may remember that in the section, “Expose services, not implementations,” we
explained that hiding your implementation classes is a good idea. Sadly, JPA entity classes
Inheritance, object-orientation, and entities
In more complex applications with multiple persistence units, it's sometimes nice
to pull out elements common to several JPA entities (such as numeric primary keys
or creation dates) into a superclass or embedded class. This is enabled by JPA's
@MappedSuperclass and @Embedded annotations. Unfortunately, this pattern
doesn't always translate into an OSGi environment. The specification requires the
persistence.xml to be in the same bundle as the entity implementations. This
restriction applies to mapped superclasses, as well as the named entities. (Any
interfaces are exempt!) This means mapped superclasses must be packaged in
the same bundles as their subclasses, which can limit their reuse.
Search WWH ::

Custom Search