Hibernate open session in view vs EclipseLink lazy loading - java

tl;dr : I see a lot of people giving advice not to use OpenSessionInView for hibernate. Does EclipseLink approach to lazy loading suffers from the same critics ?
I'm trying out hibernate after using EclipseLink for a while. I was at first shocked to have a LazyInitializationException, which EclipseLink takes care off out of the box. After gathering informations, here is my understanding of what happens behind the scene :
EclipseLink
When trying to access fields that have to be lazy loaded, it finds the entity manager in the pool and make the databases queries from there.
Hibernate
When using openSessionInView the session stays open till the view is generated.
I find the EclipseLink approach far better and I wonder why hibernate didn't take that one or if it could be implemented in it. As far as I understand, if a field has to be populated through an ajax request after the view has been rendered that wouldn't work with hibernate even with openSessionInView set to true. Also I feel like keeping the session active could be a bottleneck but my understanding is too rough to be trusted. While EclipseLink simply "close" the connection, put it back in the pool and gets it as needed.
So to the point:
Open session in view is not recommended. Does EclipseLink approach to lazy loading suffers from the same critics ?
I understand the n+1 problem but I feel like that it can be taken care off easily with logging queries and modifying the code accordingly. So even though eclipseLink suffers from that as well it's no biggie.
Are there pros and cons to both approach ? Or only cons for hibernate's approach ?
Is there a way of making hibernate take EclipseLink approach ? I've read that hibernate is more performant than EclipseLink, ence the question.

Related

hibernate vs ebean as scalable, performant ORM

We are going to write a service for which we are trying to evaluate technology stack. So as part of ORM we are thinking of using hibernate but from one of my colleague I came to know abt ebean. But we don't have any idea of ebean.
So my question is: Is there any disadvantage associated to hibernate, any salability or performance bottleneck? And what is the advantage ebean brings to the table?
What does Ebean bring to the table?
In short with Ebean it brings a full function ORM that is a lot easier to use and most importantly optimize (Well, it is easy but can also be done automatically via profiling).
A query language designed to optimise object graph construction via good support for Partial Objects and built in avoidance of N + 1
A "Sessionless" ORM ... architected to not have attach/detach semantics (So this makes it easier to use / fast to master).
Ebean now has SQL2011 History support and ElasticSearch integration. You could argue Hibernate has similar features.
Reference links:
ElasticSearch http://ebean-orm.github.io/docs/features/elasticsearch/
Automatic query tuning http://ebean-orm.github.io/docs/query/autotune
N + 1 http://ebean-orm.github.io/docs/query/nplus1
There are lot of issues with hibernate and basically any implementation of JPA in large and very scalable application. You should consider use another solution at all. Issues are well described in article Large Application Model issues and how model should look like in article Model for large applications.
As it is mentioned before, Ebean is sessionless ORM so you don't need to think about sessions. Hibernate has first level cache which is impossible to disable. It means that if you query item through ORM and then delete it directly with SQL, it stays in the cache. You can explicitly clear the cache to get the most updated results from database but unfortunately such behavior may bring errors like "detached entity passed to persist".

Replacing Seam with jee6 in conversation

A project I'm working on is going to upgrade from jee5/seam to jee6, where "those who descide" think it is a good idea to drop seam since most of its features have been incorporated into jee6. But I have a case that I doesn't seem to be able to solve in jee6.
We have several wizards using ConversationScope. We use Seams FlushModeType.Manual in order to avoid getting "dirty" data commited until we want we actually wants to commit it (each page-load basically gets it own transaction but since nothing is written to the database until we flush, most commits doesn't change the state of the database).
I have made a few attempts using PersistenceContextType.EXTENDED in jee6 but it seems like I can't find a way to defer the flush to the database like seam does and the only workarounds seems to be to use detached objects or a separate view-model.
We really like how working with attached objects make (for our cases) things really simple to understand and fast to develop.
Is there a solution where we can keep working with attached objects in conversations?
As a big fan of Seam2 I wrote great apps using conversations, conversation scoped entity manager with flush mode set to manual and detached objects.
However, we must now admit that this pattern, despite being strongly pushed in the Seam manual and working great as far as Hibernate is the JPA implementation, is fundamentally broken. The reason is explained in this post from Mark Struberg: Is There A Way To Fix the JPA EntityManager?
So, the answer is no, there is no practical solution to keep working with attached objects in conversations. You should work with detached objects.
There is another another great CDI blogger who experimented with conversation scoped entity manager: Conversational CRUD. It might be worth reading if you keep on trying to work with attached objects.

Hibernate or JDBC

I have a thick client, java swing application with a schema of 25 tables and ~15 JInternalFrames (data entry forms for the tables). I need to make a design choice of straight JDBC or ORM (hibernate with spring framework in this case) for DBMS interaction. Build out of the application will occur in the future.
Would hibernate be overkill for a project of this size? An explanation of either yes or no answer would be much appreciated (or even a different approach if warranted).
TIA.
Good question with no single simple answer.
I used to be a big fan of Hibernate after using it in multiple projects over multiple years.
I used to believe that any project should default to hibernate.
Today I am not so sure.
Hibernate (and JPA) is great for some things, especially early in the development cycle.
It is much faster to get to something working with Hibernate than it is with JDBC.
You get a lot of features for free - caching, optimistic locking and so on.
On the other hand it has some hidden costs. Hibernate is deceivingly simple when you start. Follow some tutorial, put some annotations on your class - and you've got yourself persistence. But it's not simple and to be able to write good code in it requires good understanding of both it's internal workings and database design. If you are just starting you may not be aware of some issues that may bite you later on, so here is an incomplete list.
Performance
The runtime performance is good enough, I have yet to see a situation where hibernate was the reason for poor performance in production. The problem is the startup performance and how it affects your unit tests time and development performance. When hibernate loads it analyzes all entities and does a lot of pre-caching - it can take about 5-10-15 seconds for a not very big application. So your 1 second unit test is going to take 11 secods now. Not fun.
Database Independency
It is very cool as long as you don't need to do some fine tuning on the database.
In-memory Session
For every transaction Hibernate will store an object in memory for every database row it "touches". It's a nice optimization when you are doing some simple data entry. If you need to process lots of objects for some reason though, it can seriously affect performance, unless you explicitly and carefully clean up the in-memory session on your own.
Cascades
Cascades allow you to simplify working with object graphs. For example if you have a root object and some children and you save root object, you can configure hibernate to save children as well. The problem starts when your object graph grow complex. Unless you are extremely careful and have a good understanding of what goes on internally, it's easy to mess this up. And when you do it is very hard to debug those problems.
Lazy Loading
Lazy Loading means that every time you load an object, hibernate will not load all it's related objects but instead will provide place holders which will be resolved as soon as you try to access them. Great optimization right? It is, except you need to be aware of this behaviour otherwise you will get cryptic errors. Google "LazyInitializationException" for an example. And be careful with performance. Depending on the order of how you load your objects and your object graph you may hit "n+1 selects problem". Google it for more information.
Schema Upgrades
Hibernate allows easy schema changes by just refactoring java code and restarting. It's great when you start. But then you release version one. And unless you want to lose your customers you need to provide them schema upgrade scripts. Which means no more simple refactoring as all schema changes must be done in SQL.
Views and Stored Procedures
Hibernate requires exclusive write access to the data it works with. Which means you can't really use views, stored procedures and triggers as those can cause changes to data with hibernate not aware of them. You can have some external processes writing data to the database in a separate transactions. But if you do, your cache will have invalid data. Which is one more thing to care about.
Single Threaded Sessions
Hibernate sessions are single threaded. Any object loaded through a session can only be accessed (including reading) from the same thread. This is acceptable for server side applications but might complicate things unnecessary if you are doing GUI based application.
I guess my point is that there are no free meals.
Hibernate is a good tool, but it's a complex tool, and it requires time to understand it properly. If you or your team members don't have such knowledge it might be simpler and faster to go with pure JDBC (or Spring JDBC) for a single application. On the other hand if you are willing to invest time into learning it (including learning by doing and debugging) than in the future you will be able to understand the tradeoffs better.
Hibernate can be good but it and other JPA ORMs tend to dictate your database structure to a degree. For example, composite primary keys can be done in Hibernate/JPA but they're a little awkward. There are other examples.
If you're comfortable with SQL I would strongly suggest you take a look at Ibatis. It can do 90%+ of what Hibernate can but is far simpler in implementation.
I can't think of a single reason why I'd ever choose straight JDBC (or even Spring JDBC) over Ibatis. Hibernate is a more complex choice.
Take a look at the Spring and Ibatis Tutorial.
No doubt Hibernate has its complexity.
But what I really like about the Hibernate approach (some others too) is the conceptual model you can get in Java is better. Although I don't think of OO as a panacea, and I don't look for theoritical purity of the design, I found so many times that OO does in fact simplify my code. As you asked specifically for details, here are some examples :
the added complexity is not in the model and entities, but in your framework for manipulating all entities for example. For maintainers, the hard part is not a few framework classes but your model, so Hibernate allows you to keep the hard part (the model) at its cleanest.
if a field (like an id, or audit fields, etc) is used in all your entities, then you can create a superclass with it. Therefore :
you write less code, but more importantly ...
there are less concepts in your model (the unique concept is unique in the code)
for free, you can write code more generic, that provided with an entity (unknown, no type-switching or cast), allows you to access the id.
Hibernate has also many features to deal with other model caracteristics you might need (now or later, add them only as needed). Take it as an extensibility quality for your design.
You might replace inheritance (subclassing) by composition (several entities having a same member, that contains a few related fields that happen to be needed in several entities).
There can be inheritance between a few of your entities. It often happens that you have two tables that have pretty much the same structure (but you don't want to store all data in one table, because you would loose referential integrity to a different parent table).
With reuse between your entities (but only appropriate inheritance, and composition), there is usually some additional advantages to come. Examples :
there is often some way to read the data of the entities that is similar but different. Suppose I read the "title" field for three entities, but for some I replace the result with a differing default value if it is null. It is easy to have a signature "getActualTitle" (in a superclass or an interface), and implement the default value handling in the three implementations. That means the code out of my entities just deals with the concept of an "actual title" (I made this functional concept explicit), and the method inheritance takes care of executing the correct code (no more switch or if, no code duplication).
...
Over time, the requirements evolve. There will be a point where your database structure has problems. With JDBC alone, any change to the database must impact the code (ie. double cost). With Hibernate, many changes can be absorbed by changing only the mapping, not the code. The same happens the other way around : Hibernate lets you change your code (between versions for example) without altering your database (changing the mapping, although it is not always sufficient). To summarize, Hibernate lets your evolve your database and your code independtly.
For all these reasons, I would choose Hibernate :-)
I think either is a fine choice, but personally I would use hibernate. I don't think hibernate is overkill for a project of that size.
Where Hibernate really shines for me is dealing with relationships between entities/tables. Doing JDBC by hand can take a lot of code if you deal with modifying parent and children (grandchildren, siblings, etc) at the same time. Hibernate can make this a breeze (often a single save of the parent entity is enough).
There are certainly complexities when dealing with Hibernate though, such as understanding how the Session flushing works, and dealing with lazy loading.
Straight JDBC would fit the simplest cases at best.
If you want to stay within Java and OOD then going Hibernate or Hibernate/JPA or any-other-JPA-provider/JPA should be your choice.
If you are more comfortable with SQL then having Spring for JDBC templates and other SQL-oriented frameworks won't hurt.
In contrast, besides transactional control, there is not much help from having Spring when working with JPA.
Hibernate best suits for the middleware applications. Assume that we build a middle ware on top of the data base, The middelware is accessed by around 20 applications in that case we can have a hibernate which satisfies the requirement of all 20 applications.
In JDBC, if we open a database connection we need to write in try, and if any exceptions occurred catch block will takers about it, and finally used to close the connections.
In jdbc all exceptions are checked exceptions, so we must write code in try, catch and throws, but in hibernate we only have Un-checked exceptions
Here as a programmer we must close the connection, or we may get a chance to get our of connections message…!
Actually if we didn’t close the connection in the finally block, then jdbc doesn’t responsible to close that connection.
In JDBC we need to write Sql commands in various places, after the program has created if the table structure is modified then the JDBC program doesn’t work, again we need to modify and compile and re-deploy required, which is tedious.
JDBC used to generate database related error codes if an exception will occurs, but java programmers are unknown about this error codes right.
While we are inserting any record, if we don’t have any particular table in the database, JDBC will rises an error like “View not exist”, and throws exception, but in case of hibernate, if it not found any table in the database this will create the table for us
JDBC support LAZY loading and Hibernate supports Eager loading
Hibernate supports Inheritance, Associations, Collections
In hibernate if we save the derived class object, then its base class object will also be stored into the database, it means hibernate supporting inheritance
Hibernate supports relationships like One-To-Many,One-To-One, Many-To- Many-to-Many, Many-To-One
Hibernate supports caching mechanism by this, the number of round trips between an application and the database will be reduced, by using this caching technique an application performance will be increased automatically
Getting pagination in hibernate is quite simple.
Hibernate has capability to generate primary keys automatically while we are storing the records into database
... In-memory Session ... LazyInitializationException ...
You could look at Ebean ORM which doesn't use session objects ... and where lazy loading just works. Certainly an option, not overkill, and will be simpler to understand.
if billions of user using out app or web then in jdbc query will get executed billions of time but in hibernate query will get executed only once for any number of user most important and easy advantage of hibernate over jdbc.

How can I pull objects out of hibernate and into memory. I'm hitting session problems

I have a rather enormous project in which I'm trying to retrofit in-memory data. Essentially, I have a big collection of objects which contain primitives and other objects which exist in hibernate. Large sections of non-dao code rely on lazy-loading through hibernate to hydrate objects on the fly. However, since everything exists in memory, my object are not loaded, and I get hibernate lazy loading exceptions.
I could just manually implement hibernate lazy loading by dipping to hibernate and hydrating the hibernate object manually, but the object graph for that object is huge, containing hundreds of types that would need to be initialized and set. This seems impractical, and I'm looking for a viable solution to this problem. If anyone has ANY kind of tips, hints, solutions, or stories relating to this kind of problem or similar problems, I would be very grateful.
Thanks much.
If you are handling the sessions by hand, try passing object ids (row ids in the database) instead of full objects. Then preform a database read when you want to get the full blown ORM object and only keep the ORM object in a limited scope so it could be garbage collected when you were done with it. This would probably save you some memory.
This has a side effect of also limiting the amount of time you need an open session for. As you could open sessions (I would recommend a session factory) and close them as needed. However, I think there may be a significant database hit for opening and closing sessions (I think the underlying transaction is the real problem). You may want to look into JPA, which as far as I understand, doesn't need a transaction for reads. Spring also has some nice features to automate transaction and session management they may want to investigate.
You probably have session already closed. Try to keep the session open when data is lazy loaded or if this is not possible, do eager load by specifying lazy="false" attribute on the collection (lazy="true" is the default).
The most common cause of a LazyInitializationException is that the hibernate session is closed. Keep the hibernate session open and you should be fine.
Please note that if you're using the Spring HibernateTemplate to load objects, the objects that you load will necessarily be detached. If you're building a webapp using Spring MVC, an easy way around this is to use the OpenSessionInViewInterceptor.

Spring and Hibernate, Lazy initiation problem

Hey I am developing an desktop application using Spring and Hibernate, and I have a problem with lazy initiation. I looked in the web and every solution is related to the open session in view pattern, but I can't use this pattern. I've also tried to get the sessionfactory from the HibernateTemplate, but it returns to me a disconnected session.
Does anyone know other solution?
I would suggest that you basically have two solutions:
Make arrangements to keep a Hibernate session open when you access a lazy-initialized object or collection. That means you're going to have to carefully mark your transaction boundaries in your code, a la the "open session in view" pattern. Spring makes this possible, but in a desktop application it won't be as straightforward as a web application where the transaction boundaries are a little more obvious.
Turn off all the lazy-initialization for your persisted objects in Hibernate.
Option 2 could lead to a lot of unnecessary database access, and option 1 means you have to seriously study your workflow and use cases.
Hope that helps!
One option is to call Hibernate.initialize() on the entities or collections to force initialize them. You'd want to do this before you return the data back to your view. I would consider this carefully, since it's going to generate a lot of SQL statements back to the database.
You may want to look into using "fetch" in your HQL queries or configuration the fetch mode to "eager" in your mappings (I believe it's FetchMode.EAGER in JPA or lazy="false" in hbm.xml).
#Jose: Don't manage the Session in your own ThreadLocal. Use SessionFactory.getCurrentSession() and configure Hibernate to use the "thread" SessionContext.
I had a very similar problem, and as I was not able to find any really appropriate solution to it. I came up with my own one combining a lot of different approaches found on the web and posted them to my blog.
Sorry, that I don't put it in all here, but it is to much work to do it over and over again in all the forums I found people having this or a similar problem
Remote Lazy Loading with Hibernate and Spring

Categories

Resources