Remove Proxy Code from Entity during Serialization - java

I have a server and clients that are both Java-based and communicate with each other over RMI. The server's data access layer is implemented with JPA and Hibernate and entities are often used as parameters.
The clients do not have Hibernate code and dynamic code download is disabled, so when the server sends an entity to its clients, the actual entity must be sent, not the proxy. Moreover, the entity must be sent as-is, without pre-loading all lazy-fetched attributes because they will never be needed by the clients in most cases.
Is it possible to implement these requirements with Hibernate?

you can fetch all properties in the query
from docs
If you are using property-level lazy fetching (with bytecode instrumentation), it is possible to force Hibernate to fetch the lazy properties in the first query immediately using fetch all properties.
from Document fetch all properties order by name
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html
or use eagle fetch in your mapping...

The only clean way I know of (that is without fetching every association for the object) is to use a separate object layer for data transportation.
Alternatively you can send the same object types repopulated by you with the necessary data, instead of hibernates objects with the proxies set.

Related

Hibernate Enverse in Java is using Proxies instead of Bags

Currently i'm worrking on a Java project which uses JPA and under the hood Hibernate as its ORM.
Furthermore we're using Enverse as our auditing Library.
Now, when i query an entity which contains a #ManyToMany or #OneToMany relation directly through Hibernate, the embedded collections will get mapped to "Bag-Types" (PersistentBag for Lists and PersistentSet for Sets).
These Wrapper implement the "PersistentCollection" Interface, which handles the lazy Loading.
When the parentobject ist accessed, no database query will be executed (seen in the debugger). Only when i access an element of the collection, a database query is submittet.
But when i query the Revision through an AuditReader, the Collections will be wrapped in a ListProxy or a SetProxy, this leads to an "unexpected" behaviour (since enverse is a core element of hibernate). In this case, when i just access the parent object, every element in the embedded collection is directly queried. This leads to an enormous performance drop.
The Response from the Revision Endpoint is wrapped into RepresntationModel (from the Spring Hateos project). This leads to the access of the parent object and the generell collection, to create the "_embedded" Object of the response. With the PersistentBag there is no problem, but with the ListProxy, every Element gets queried from the database, leading to thousands of requests.
Is there a way to "teach" enverse to use PeristentBag (or PersistentSet) instead of the internal Proxy Collections or is there another workaround to not load the entire Collection?
Ignoring the embedded Ressources in the Revision boosts the performance, but is no solution since the references are Lost.
Enverse ignores the "fetch" configurations on Collection-Annotations (every Collection is fetched lazy), so this also does not do the trick.
Since the revision endpoint is highly generic, using projections is not an option.

What is the relationship between DTO and lazy-loading in Hibernate

I know what is DTO: An object that carries data between processes in order to reduce the number of method calls.
and I know what is lazy-loading in hibernate.
I read this sentences in "Full Stack Development with JHipster" book :
JHipster uses DTO (Data Transfer Object) and VM (View Model) on the server side. DTOs are for transferring data from the service layer to and from the resource layer. They break the Hibernate transactions and avoids further lazy loading from being triggered by the resource layer.
I don't understand the relationship between DTO and lazy loading.
Lazy loading is for entities, not DTOs.
A JPA entity can be represented as a POJO or a Proxy.
Using EntityManager.find gives you a POJO:
Post post = entityManager.find(Post.class, postId);
While the EtityManager.getReference method gives you a Proxy:
Post post = entityManager.getReference(Post.class, postId);
The POJO has its basic properties initialized because a SELECT statement was executed to fetch the entity. The Proxy does not hit the database upon creation. Only the id is set based on the provided entity identifier. Only you access the Proxy properties, a SELECT statement will be executed.
Proxies are also used for collections (e.g. #OneToMany or #ManyToMany) which are using the FetchType.LAZY strategy by default. Once you access the LAZY collection, a SELECT statement will be executed to fetch the associated collection.
Now, a DTO is based on a projection, hence a SELECT statement is executed prior to populating the DTO. For this purpose, you can say that the DTO is eagerly loaded every time.
DTOs are much more efficient than entities for read-only projections because you load just the table columns that you explicitly requested.
If you pass Hibernate managed persistent entities to the resource layer with LazyLoading enabled, the resource layer will invoke get-methods in order to read their properties some of which are possibly not initialized at that time. Hibernate will then lazily load the data of that particular property from the persisntet store, sending an SQL statement (possibly each time starting and committing a new transaction) and waiting for response which is quite slow. If this happens hundred of times, each time having to initialize another property, each time triggering a lazy load, the user has to wait...
If you prepare a DTO in your service layer, containing all the data relevant to the resource layer, read access to that DTO is highly efficient without the risk of hitting the database for any get-method invokation as everything relevant is in memory already. No subsequent lazy load will be triggered.
In Simple terms: If you call getter of a lazy loading marked field, Hibernate will make a db query for that data.
This is one of the reasons you should not return Entities as backend response... any JSON conversion(Serialization)/getter call will trigger unwanted loading of the data.
whereas a DTO is made specifically to transfer data as per use and you create DTO from these Entities (Multiple DTO can be created from one Entity) and pick only required data fields
Eg.
User entity: has user details and list of friends
UserDetailsDTO: would only require the details and dont need 1000's of friends mapped to the user... and their friends...
UserFriendsDTO: we can selectively get the friends names or ids for this DTO

Spring Hibernate JPA - Using many schemas

The company I am working for stores their client data in a separate database schema for each client. They indicate that this cannot be changed at this time. Is there an efficient way to pull data and update data in all schemas without configuring a connection for each schema? Everything I can find when I search seems to be talking about using one or a couple of schemas, but I need to use many (100+) simultaneously.
In any given persistence context, each JPA entity class is mapped to a specific base table. Whether and how easily you can access multiple schemas via a single DB connection is a function of your DBMS, your JDBC driver, and perhaps your particular database, but even a combination that in general supports the kind of access you would need will still not allow you to map the same entity class to multiple distinct base tables in the same persistence context.
You might be able to use the same entity classes for different clients by associating a different persistence context with each client, but that will not allow you use the same DB connection for all of them. Thus, if using the same connection were possible for you at all, it would require different entity classes per client.
Have you considered creating a new DB user and creating SYNONYMS for each of the tables in the separate database schemas ?
You could then map JPA entitys to the SYNONYM names that you have created..
Using this approach you could still use the one DB connection but with SYNONYMS to the DB tables in the other schemas...

Hibernate: Empty collection instead of Lazy-load error

I have an ORM entity loaded by Hibernate, with certain associations LAZY loaded when I need them. This entity is transported thru MQ to client application (and the client is .NET, so I'm using MessagePack to serialize/deserialize) and when the entity is serialized by MsgPack, it tries to access the lazy loaded association and it fails, as the session is already closed. And even if it did not failed, I do not want it to load the association in some cases.
Is there a way to tell hibernate to fill the lazy associations with empty values instead of proxies for some query results or do I have to iterate the returned list and perform these changes by myself?
Thanks for your answers!
You have no other way, but to use DTO objects, to tranfer it through MQ,
Load entity from DB using hibernate
convert it to DTO object which implents Serializable.
Transfer it to consumer using MQ
Convert it to any other entity on other side.
I think that #Transient only applies to ORM. If you do not want your field to be serialized, you should use key word "transient".
private transient List<Object> myTransientList;

JPA merge in a RESTful web application with DTOs and Optimistic Locking?

My question is this: Is there ever a role for JPA merge in a stateless web application?
There is a lot of discussion on SO about the merge operation in JPA. There is also a great article on the subject which contrasts JPA merge via a more manual Do-It-Yourself process (where you find the entity via the entity manager and make your changes).
My application has a rich domain model (ala domain-driven design) that uses the #Version annotation in order to make use of optimistic locking. We have also created DTOs to send over the wire as part of our RESTful web services. The creation of this DTO layer also allows us to send to the client everything it needs and nothing it doesn't.
So far, I understand this is a fairly typical architecture. My question is about the service methods that need to UPDATE (i.e. HTTP PUT) existing objects. In this case we have these two approaches 1) JPA Merge, and 2) DIY.
What I don't understand is how JPA merge can even be considered an option for handling updates. Here's my thinking and I am wondering if there is something I don't understand:
1) In order to properly create a detached JPA entity from a wire DTO, the version number must be set correctly...else an OptimisticLockException is thrown. But the JPA spec says:
An entity may access the state of its version field or property or
export a method for use by the application to access the version, but
must not modify the version value[30]. Only the persistence provider
is permitted to set or update the value of the version attribute in
the object.
2) Merge doesn't handle bi-directional relationships ... the back-pointing fields always end up as null.
3) If any fields or data is missing from the DTO (due to a partial update), then the JPA merge will delete those relationships or null-out those fields. Hibernate can handle partial updates, but not JPA merge. DIY can handle partial updates.
4) The first thing the merge method will do is query the database for the entity ID, so there is no performance benefit over DIY to be had.
5) In a DYI update, we load the entity and make the changes according to the DTO -- there is no call to merge or to persist for that matter because the JPA context implements the unit-of-work pattern out of the box.
Do I have this straight?
Edit:
6) Merge behavior with regards to lazy loaded relationships can differ amongst providers.
Using Merge does require you to either send and receive a complete representation of the entity, or maintain server side state. For trivial CRUD-y type operations, it is easy and convenient. I have used it plenty in stateless web apps where there is no meaningful security hazard to letting the client see the entire entity.
However, if you've already reduced operations to only passing the immediately relevant information, then you need to also manually write the corresponding services.
Just remember that when doing your 'DIY' update you still need to pass a Version number around on the DTO and manually compare it to the one that comes out of the database. Otherwise you don't get the Optimistic Locking that spans 'user think-time' that you would have if you were using the simpler approach with merge.
You can't change the version on an entity created by the provider, but when you have made your own instance of the entity class with the new keyword it is fine and expected to set the version on it.
It will make the persistent representation match the in-memory representation you provide, this can include making things null. Remember when an object is merged that object is supposed to be discarded and replaced with the one returned by merge. You are not supposed to merge an object and then continue using it. Its state is not defined by the spec.
True.
Most likely, as long as your DIY solution is also using the entity ID and not an arbitrary query. (There are other benefits to using the 'find' method over a query.)
True.
I would add:
7) Merge translates to insert or to update depending on the existence of the record on DB, hence it does not deal correctly with update-vs-delete optimistic concurrency. That is, if another user concurrently deletes the record and you update it, it must (1) throw a concurrency exception... but it does not, it just inserts the record as new one.
(1) At least, in most cases, in my opinion, it should. I can imagine some cases where I would want this use case to trigger a new insert, but they are far from usual. At least, I would like the developer to think twice about it, not just accept that "merge() == updateWithConcurrencyControl()", because it is not.

Categories