tags:

views:

541

answers:

3

What is the best practice in using JPA Entities?

Since JPA entities are just POJOs, is it considered appropriate to use the object as a data object in other parts of the system or should I convert them to another data object?

Is it acceptable to use the JPA Entity POJOs in other parts of the system unrelated to JPA?

+2  A: 

Entities are now themselves capable of transporting their own data so why bother converting them into something else? In other words, I tend to agree with DTO an AntiPattern in EJB 3.0:

The heavy weight nature of Entity Beans in EJB specifications prior to EJB 3.0, resulted in the usage of design patterns like Data Transfer Objects (DTO). DTOs became the lightweight objects (which should have been the entity beans themselves in the first place), used for sending the data across the tiers. [...]

EJB 3.0 spec makes the Entity bean model same as Plain old Java object (POJO). With this new POJO model, you will no longer need to create a DTO for each entity or for a set of entities. If you want to send the EJB 3.0 entities across the tier make them just implement java.io.Serialiazable.

Pascal Thivent
Crediting you with answer because you linked to interesting documentation on antipattern.
Tazzy531
+2  A: 

It depends on what you mean with "other parts". Since your JPA Entities have to be somehow related to your system why not use them since they are already there. The important point is, that you don't use the same class for two entirely different concerns (which is then imho either an indication of bad design or just a really big system). Everything else will probably just end up in an endless mapping around between your different POJOs hassle.

For example a user Login. It might be common verbose Java practise to create a separate UserLoginForm Bean for a web based login but consider this:

You already have your user JPA entities (and therefore a user POJO) in the database (it has a username, password hash, address and probably other stuff stored). You can use exactly the same object in your login request from the web form as well (some Frameworks like Spring will map it right away). Create an empty User object, set the username and the hashed password and make a JPA Query by example. If that query returns exactly one result the login is valid and you can store the loaded user object in the session.

Daff
+1  A: 

This is a good question.

By exposing JPA entity classes to the rest of the system you expose the persistence mechanism and object to db mapping.You lose control over how these objects are CRUDded and managed. By breaking persistence encapsulation, a change can have a ripple effect on the rest of the system.

Future changes to system persistence may be impossible, awkward, limited and/or risky. Example: you may need to optimise for performance and/or scalability. This may require caching, db schema changes, non RDBMS usage, multiple databases. Encapsulation also helps to mitigate migration to future db schemas.

So the trade off is:

  • managing and maintaining an application persistence layer on top of JPA which encapsulates persistence. i.e. an interface. OR
  • decide to use JPA across the board in your architecture. Accept the fact that future changes may have system wide effects.

The first option may be necessary if frequent system wide changes are not acceptable - e.g. 3rd parties are accessing your data. Or perhaps you've decided on a 3 layer architecture: GUI, business logic, persistence.

The second option is ok if you have an agile development process and have control over the whole system and accept the fact that system wide change may be necessary down the line.

Conor