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.
Related
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 ?
We are using JPA + Hibernate.
I have some Many-to-one mappings which are lazy loaded.
In Service, I Initiallize the Many-to-one objects by calling their getter method. but proxy gets assigned to parent VO and not actual VO Object.
My Question is, Is there any way in JPA to force to use no proxy Strategy.
My limitation here is i cant use Hibernate Objects or annotaions like #LazytoOne etc.
thanks in advance.
You cannot prevent Hibernate from using proxy objects there due to the fact that somehow it has to guarantee it's a lazy relation.
You have multiple choices:
Trigger the initialization Hibernate.initialize(parent.getChild()). Note that this is not the best way to do it and this also requires an active transaction.
Fetch the relation when fetching the entity itself. This can be done with the Fetch Joins. JPQL/HQL/Criteria API are capable of doing this.
Use read-only projections which contains only the data you need. For this particular case you can use Spring Data JPA as it comes with such a feature.
I suggest you to go with either option 2 or 3 as they are the most effective ways to do this.
Furher reading about lazy-loading here.
I am Thinking of creating A JPA 2.0 Mapping of an entity, however I do not want to have any setters or expose a constructor, I want to use a Factory to create my class whenever it is fetched from the db.
I have taken a look at the pro JPA 2.0 book and some articles online, but cannot find anything similar, has anyone done anything like this?
Thank you,
Use field access and add a private constructor. JPA can access private fields.
Factory pattern actually is a good candidate for JPA Entities. However it is practically impossible to make entity manager use your custom factory on fetching unless you make your own JPA implementation.
But there are still many applications of factory, especially for CRUD programms. The most important IMHO is context depending defaults for fields, concerning user created new entities of course.
For full stack java-ee applications I prefer to use Singleton EJB for this purpose, as it has easy access to JPA Entity manager.
You can make protected constructor for entity to prevent user instantiation.
I was experimenting with eclipselink. I am trying to update an existing entity in database. The JPA entity only has public fields and fields are annotated with JPA annotation. The code loads an entity using EntityManager.find().
The code creates an instance of JPA entity, assigns value to public fields of the entity and invokes EntityManager.merge(entity) method. Eclipselink does not update database record. I enabled log to see whether Eclipselink issues SQL statement or not.
Eclipselink does not issue any update statement. Does this mean that even if I use field persistence, I can not assign value to public fields of the entity instead of using setter method?
Thanks,
Chir
Weaving introduces some optimizations such as lazy onetoone and manytones and change tracking. The only way these can work is if you use the accessor method on the entity, but if that isn't an option, you can turn them off as needed. See
http://eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_changetracking.htm
For details on change tracking.
I am developing an application in Flex, using Blaze DS to communicate with a Java back-end, which provides persistence via JPA (Eclipse Link).
I am encountering issues when passing JPA entities to Flex via Blaze DS. Blaze DS uses reflection to convert the JPA entity into an ObjectProxy (effectively a HashMap) by calling all getter methods on the entity. This includes any lazy-initialised one/many-to-many relationships.
You can probably see where I am going. If I pass a single object through JPA this will call all one/many-to-many methods on this object. For each returned object if they have one/many-to-many relationships they will be called too. As such, by passing back a single JPA entity I actually end up doing multiple database calls and passing all related entries back as a single ObjectProxy instance!
My solution to date is to create a translator to convert each entity to an ObjectProxy and vice-versa. This is clearly cumbersome and there must be a better way.
Thoughts please?
As an alternative, you could consider using GraniteDS instead of BlazeDS: GraniteDS has a much more powerful data management stack than BlazeDS (it competes more with LCDS) and fully support lazy-loading for all major JPA engines: Hibernate, EclipseLink, OpenJPA, etc.
Moreover, GraniteDS has a great client-side transparent lazy loading feature and even a so-called reverse lazy-loading mechanism.
And you don't need any kind of intermediate DTOs: it serializes JPA entities as is and uses code-generated ActionScript beans on the client-side to keep their initialization states.
Unfortunately, lazy-loading is not easy to accomplish with Flash clients. There are some working solutions, like dpHibernate, but so far all the different solutions I have tested fall short of what you would expect in terms of performance and ease of use.
So in my experience, it is the best and most reliable solution to always use DTOs, which adds the benefit of cleanly separating the database and view layers. This necessitates, though, that you implement either eager loading, or a second server round trip to resolve your many-to-many relations, as well as a good deal more boilerplate code to copy the DAO and DTO field values.
Which one to choose depends on your use case: Sometimes getting only the main object's fields might be enough, then you could simply omit the List of related objects from your DTO (transfer only those values you need for your query). Sometimes you may actually need the entire list of related entities, and then you could get it via eager loading, or by setting up a second remote object to find only the list.
EclipseLink also provides a copyObject() API that allows you to give a copy group of exactly what attribute you want. You could then use this copy to avoid having the relationships that you do not want.
If you have a detached object, you could just null out the fields that you do not want as well, or use a DTO.