JPA best practices? [closed]

有些话、适合烂在心里 提交于 2019-12-08 17:11:40

问题


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?


回答1:


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.




回答2:


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.




回答3:


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.




回答4:


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 ;)




回答5:


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;
}



回答6:


You may need to use another set of classes to prevent ripple effect. This is often the case with web services that have several dependencies. Data mapping in general adds to complexity of program and should be avoided without a valid reason.




回答7:


My $0.20

Unless you can remember how relationships are marked in your code and when they are populated by hibernate and when/where they are accessed in the code I would suggest you to go with DTO approach.

However, if you are learning hibernate or going to use it in small project it may be easy for you to return the entity (or a collection of them) from your controller layer.

But I'm sure the more you do it the more you will find the need to move to DTO or even JsonView. If you are not the one who is building UI then you will realize it even sooner.

Speaking of DTO, my fav is ModelMapper. You can do conversion (simple and complex whatever you like) at controller layer. This way you will know what you are returning inside the DTO.




回答8:


See the slides of JPA Best Practices of Lee Chuk Munn. You can find it in JPA Best Practices - Indo Java Podcast.



来源:https://stackoverflow.com/questions/7086433/jpa-best-practices

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!