I am currently working on a code where the entity loaded from DB needs multiple updates based on the use case. I am striving to prevent mutable objects in my code. Given how hibernate works, I see that I have no choice but to allow entities as mutable so as to invoke setters to update the entity.
Is there a way around this ?
Related
I'm using Spring Boot JPA Data with Hibernate under the hood. From quick testing it seems that using public fields instead of traditional getter/setter ceremony works fine. I was able to retrieve data, change field value and it was properly persisted back.
I expect slight performance degradation, because hibernate will be forced to compare all attributes at the end of transaction instead of some kind of dirty flag set in setters (although I'm not sure if it works like that).
Also I expect that lazy field values will not work (they need getter), though lazy collections should work.
According to Hibernate documentation:
The JPA specification requires this, otherwise, the model would prevent accessing the entity persistent state fields directly from outside the entity itself.
Although Hibernate does not require it, it is recommended to follow the JavaBean conventions and define getters and setters for entity persistent attributes. Nevertheless, you can still tell Hibernate to directly access the entity fields.
So it's not really clear to me which features depend on getters/setters presence.
I'm new to ORM and hibernate.
my application is of complex design pattern. with builders, fluent interface.
and those objects also throws exceptions while creating illieagel objects. and I use orm mapping to access database. I convert those ORM entities to my complex objects and vise versa. is it good idea or any other alternate.
As a general rule, you should create business objects (in your case they exist already) when you truly need them. So, if your application needs those complex objects, that is fine (but keep in mind that they are hard to maintain as you will have to change a bunch of objects when you make a change in your database and Hibernate objects).
If you could get rid of those complex objects, you could use Hibernate's detached entities as simple DTOs all over your application and you won't have the difficulty of maintaining two sets of objects. On the other hand, using business objects can make your web layer (or other layers) independent of Hibernate and its entities, so makes your life easier if somehow in the future you decide not to use Hibernate. From my experience, if the recent is not your case and you are thinking of Hibernate as a long term solution, using Hibernate's detached entities is a much easier solution.
Do you have some requirements which says that you need two kind of entities: those rich/complex and those ORM based?
I used ORM along with domain driven design and it worked fine. We decoupled rich entities (and value objects) from services and those entities were persisted from aggregate downwards.
You certainly must slightly change those entities when you want to use hibernate mapping but I haven't find anything which would break our DDD model. E.g. parameterless constructor can be private etc.
As we used fluent/xml mapping, model was completely separated from persistence layer, see term persistence ignorance
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
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?
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.
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.
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.
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 ;)
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
the java REST clients to use
the REST server accepts this object as a parameter, and
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;
}
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.
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.
See the slides of JPA Best Practices of Lee Chuk Munn. You can find it in JPA Best Practices - Indo Java Podcast.
With the introduction of Hibernate in my project, my code started getting really coupled, and boilerplate in many places (and it should be the other way round, right?)
I got pretty confused by a particular example. I've always considered DAO objects to be pretty generic in their nature (mostly encapsulating the basic CRUD oeprations as well as the backend storage implementation)
Unfortunately, as my entity classes started to get more complicated, I started offloading more and more logic to the DAO objects. I have a particular example:
my entity class User should have a relation called friends, which is essentially a collection of users. However, I have to map my class to a collection of UserFriendship objects instead, each of which contains a ref to the friend object, but also other specific friendship data (the date when the friendship occurred)
Now, it is easy to introduce a custom getter in the entity class, which will take the collection of UserFriendship objects and turn it into a collection of User objects instead. However, what if I need only a subset of my friends collection, say, like in paging. I cannot really do that in the entity object, because it doesn't have access to the session, right? This also applies to when I need to make a parametrized query on the relationship. The one that has the access to the session is the UserDAO. So I ended up with this
UserDAO
=> normal CRUD methods
=> getFriends(Integer offset, Integer limit);
=> a bunch of similar getters and setters responsible for managing the relationships within the User instance.
This is insane. But I cannot really do anything else. I am not aware if it is possible to declare computed properties within the entity classes, which could also be parametrized.
I could technically also wrap the DAO within the entity, and put the helper getters and setters back into the entity class, where they should be, but I am not sure whether if that is a good practice as well.
I know that the DAO should only be accessed by the controller object, and it should provide a more or less complete entity object or a set of entity objects.
I am deeply confused. More or less all of my DAO objects now couple logic that should be either in the Entity objects or in the controllers.
I am sorry if my question is a bit confusing. It is a bit hard to formulate it.
My general rules are:
in the entity classes, respect the law of Demeter: don't talk to strangers
the entity classes must not use the session
the controller/service classes must not use the session. They may navigate in the graph of entities and call DAO methods
DAO methods should be the ones using the session. Their work consists in getting, saving, merging entities and executing queries. If several queries or persistence-related actions should be executed for a single use-case, the controller/service should coordinate them, not the DAO.
This way, I can test the business logic relatively easily by mocking the DAOs, and I can test the DAOs relatively easily because they don't contain much logic. Most of the tests verify that the queries find what they're supposed to find, return them in the appropriate order, and initialize the associations that must be initialized (to avoid lazy loading exceptions in the presentation layer, where I'm using detached objects)
I'm building an application using JPA 2.0 (Hibernate implementation), Spring, and Wicket. Everything works, but I'm concerned that my form behaviour is based around side effects.
As a first step, I'm using the OpenEntityManagerInViewFilter. My domain objects are fetched by a LoadableDetachableModel which performs entityManager.find() in its load method. In my forms, I wrap a CompoundPropertyModel around this model to bind the data fields.
My concern is the form submit actions. Currently my form submits pass the result of form.getModelObject() into a service method annotated with #Transactional. Because the entity inside the model is still attached to the entity manager, the #Transactional annotation is sufficient to commit the changes.
This is fine, until I have multiple forms that operate on the same entity, each of which changes a subset of the fields. And yes, they may be accessed simultaneously. I've thought of a few options, but I'd like to know any ideas I've missed and recommendations on managing this for long-term maintainability:
Fragment my entity into sub-components corresponding to the edit forms, and create a master entity linking these together into a #OneToOne relationship. Causes an ugly table design, and makes it hard to change forms later.
Detach the entity immediately it's loaded by the LoadableDetachableModel, and manually merge the correct fields in the service layer. Hard to manage lazy loading, may need specialised versions of the model for each form to ensure correct sub-entities are loaded.
Clone the entity into a local copy when creating the model for the form, then manually merge the correct fields in the service layer. Requires implementation of a lot of copy constructors / clone methods.
Use Hibernate's dynamicUpdate option to only update changed fields of the entity. Causes non-standard JPA behaviour throughout the application. Not visible in the affected code, and causes a strong tie to Hibernate implementation.
EDIT
The obvious solution is to lock the entity (i.e. row) when you load it for form binding. This would ensure that the lock-owning request reads/binds/writes cleanly, with no concurrent writes taking place in the background. It's not ideal, so you'd need to weigh up the potential performance issues (level of concurrent writes).
Beyond that, assuming you're happy with "last write wins" on your property sub-groups, then Hibernate's 'dynamicUpdate' would seem like the most sensible solution, unless your thinking of switching ORMs anytime soon. I find it strange that JPA seemingly doesn't offer anything that allows you to only update the dirty fields, and find it likely that it will in the future.
Additional (my original answer)
Orthogonal to this is how to ensure you have a transaction open when when your Model loads an entity for form binding. The concern being that the entities properties are updated at that point and outside of transaction this leaves a JPA entity in an uncertain state.
The obvious answer, as Adrian says in his comment, is to use a traditional transaction-per-request filter. This guarantees that all operations within the request occur in single transaction. It will, however, definitely use a DB connection on every request.
There's a more elegant solution, with code, here. The technique is to lazily instantiate the entitymanager and begin the transaction only when required (i.e. when the first EntityModel.getObject() call happens). If there is a transaction open at the end of the request cycle, it is committed. The benefit of this is that there are never any wasted DB connections.
The implementation given uses the wicket RequestCycle object (note this is slightly different in v1.5 onwards), but the whole implementation is in fact fairly general, so and you could use it (for example) outwith wicket via a servlet Filter.
After some experiments I've come up with an answer. Thanks to #artbristol, who pointed me in the right direction.
I have set a rule in my architecture: DAO save methods must only be called to save detached entities. If the entity is attached, the DAO throws an IllegalStateException. This helped track down any code that was modifying entities outside a transaction.
Next, I modified my LoadableDetachableModel to have two variants. The classic variant, for use in read-only data views, returns the entity from JPA, which will support lazy loading. The second variant, for use in form binding, uses Dozer to create a local copy.
I have extended my base DAO to have two save variants. One saves the entire object using merge, and the other uses Apache Beanutils to copy a list of properties.
This at least avoids repetitive code. The downsides are the requirement to configure Dozer so that it doesn't pull in the entire database by following lazy loaded references, and having yet more code that refers to properties by name, throwing away type safety.