Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA best practices? [closed]

I’m working on a little multi-tier application utilizing JPA/EclipseLink as a persistence layer. In my current design I have two sets of objects, POJOs and Entity objects, I use POJOs for general programming tasks and Entity classes are used for DB read/write and table mapping.

Now is it necessary to have POJO=>Entity mapping (problematically) and then a second Entity==>DB tables mapping (JPA annotations)? I find it easier to just use Entity classes as my main java objects and persist them whenever necessary, after all Entity classes are essentially POJO with with couple of JPA annotations.

Also in a situation where it's indeed necessary to keep things separated, what is the best place to do the POJO=>Entity mapping, currently I do this in a CRUD method, e.g.

public void addCustomerPOJO(Customer customerPOJO){
   //Cteat EntityManager and start a Transaction

   //Create Entity class and populate it with values 
   //from the passed-in regular (non entity) Customer class

  //Persiste and close
}

Is there a better or more common way to do this?

like image 939
Hay Avatar asked Aug 16 '11 23:08

Hay


5 Answers

There is nothing wrong with using your entities as your domain objects. You have to be aware of using entities that have been detached and whatnot, but that can be managed.

I would not artificially create work for yourself by forcing each entity to be mapped to another bean (or POJO). Sometimes it is necessary to wrap many entities (or values from entities) into a bean, but only do it if there is a good reason.

like image 84
Jeremy Avatar answered Oct 16 '22 16:10

Jeremy


Maybe the confussion is due to the fact that the entity is just a POJO with the mappings info (in the code as annotations or in a separate configuration file). Works as a POJO as long as you want (you can create and modify objects; as long as you don't save them with a Session they won't be written in the DB).

Sometimes you might need to have the data in a bean that is not an Entity (mainly because that bean is managed by another framework and you do not want to mix things *1), then you only have to copy (by an specific constructor, by calling lots of set...(), whatever) that data from your bean to your Entity/POJO.

*1 I am thinking of JSF here.

like image 37
SJuan76 Avatar answered Oct 16 '22 17:10

SJuan76


I see no reason for two parallel object hierarchies like this. I'd have entities and ditch what you're calling POJOs. No need for mapping. It's a waste of CPU cycles for no benefit that I can see.

like image 37
duffymo Avatar answered Oct 16 '22 17:10

duffymo


I am currently working on a three-tired Java EE app with JPA serving the back end. I use a single java class to represent each table in the database(entity classes) And i use the same classes to do all the operations, both in the business layer as well as the database layer. And it makes sense too. Because in all the three layers, you can create an instance of the same entity class independently.

PS - @Hay : Even when i started learning JPA, I was doing manipulations with two different sets of same classes as you :) I guess, this practice emerged becoz of EJB 2.1 which didn't have any annotations in them. So basically two different sets of classes are required where one has to be entirely dedicated as ENTITY CLASSES for DAO operations. As JPA evolved, Annotations are brought into picture, which made our lives easy.. OLD HABBITS DIE HARD indeed ;)

like image 2
Arun GK Avatar answered Oct 16 '22 18:10

Arun GK


Annotations do have their downside, especially in multi-tiered Java EE applications.

In the example below, you have a simple POJO object (Domain object) which you want

  1. the java REST clients to use
  2. the REST server accepts this object as a parameter, and
  3. to persist this object to a database.

I would think this is a common use-case.

With so many annotations the clients using this object needs all the jar dependencies. I suppose the annotations can be moved to an XML file, but then the annotation advantages are lost.

Are there any other creative solutions?

@Data
@Entity
@XmlRootElement(name="sport")
@Table(name = "db_sport")
@NamedQueries({
   @NamedQuery(name = "Sport.findAll", query = "SELECT d FROM Sport d")})
public class Sport implements Serializable {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Basic(optional = false)
   @Column(name = "sportId")
   int sportId;
}
like image 1
java4africa Avatar answered Oct 16 '22 17:10

java4africa