views:

876

answers:

6
+6  Q: 

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.

+5  A: 

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.

cletus
thanks, I will check out Ibatis.
jinxx0r
+4  A: 

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.

Brian Yarger
+1  A: 

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.

grigory
+4  A: 

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

KLE
+17  A: 

Good question with no single simple answer.

I used to be a big fan of Hibernate. Multiple projects, multiple years of experience. 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 loose 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 debuging) than in the future you will be able to understand the tradeoffs better.

Gregory Mostizky
+1 excellent answer. I'm glad my vote sets it as first with 4 votes
KLE
+1 Great answer.. I used to think Hibernate was the best thing ever, but as our application grew in complexity (Larger object graphs), I have ran into a few scenarios where debuging was a nightmare because I had no idea what hibernate was doing. (Luckily, it's open source so I was able to dig through the source to figure it out. NOT FUN) Anyway, I agree.. No Free Meals. Hibernate is great, but there are tradeoffs.
delux247
A: 

... 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.

Rob