开发者

Disadvantages of Object Relational Mapping

开发者 https://www.devze.com 2023-04-03 11:14 出处:网络
I am a fan of ORM - Object Relational Mapping and I have been using it with Rails for the past year and a half. Prior that, I use to write raw queries using JDBC and make Database do the heavy lifting

I am a fan of ORM - Object Relational Mapping and I have been using it with Rails for the past year and a half. Prior that, I use to write raw queries using JDBC and make Database do the heavy lifting via Stored Procedures. With ORM, I was initially happy to do stuff like coach.manager and manager.coaches which were very simple and easy to read.

But as time went by there were in-numerous associations creeping up and I ended up doing a.b.c.d which were firing queries 开发者_如何学Goin all directions, behind the scenes. With rails and ruby, the garbage collector went nuts and took insane time to load a very complex page which involves relatively lesser data. I had to replace this ORM style code by a simple Stored procedure and the result I saw was enormous. A page that took 50 seconds to load now takes only 2 seconds.

With this huge difference, should I continue using ORM? It is very clear it has severe overheads compared to a raw query.

In general, what are the general pitfalls of using an ORM framework like Hibernate, ActiveRecord?


An ORM is only a tool. If you don't use it correctly, you'll have bad results.

Nothing stops you from using dedicated HQL/criteria queries, with fetch joins or projections, to return the information that your page must display in as few queries as possible. This will take more or less the same time as dedicated SQL queries.

But of course, if you just get everything by ID and navigate through your objects without realizing how many queries it generates, it will lead to long loading times. The key is to know exactly what the ORM does behind the scene, and decide if it's appropriate or if another strategy must be adopted.


I think you've already identified the major tradeoff associated with ORM software. Every time you add a new layer of abstraction that tries to provide a generalized implementation of something that you used to do by hand there is going to be some loss of performance/efficiency.

As you noted, traversing multiple relationships such as a.b.c.d can be inefficient, because most ORM software will be doing an independent database query for each . along the way. But I'm not sure that means you should eliminate ORM altogether. Most ORM solutions (or at least, certainly Hibernate) allow you to specify custom queries where you can bring back exactly what you want in a single database operation. This should be about as fast as your dedicated SQL.

Really the issue is about understanding how the ORM layer is working behind the scenes, and realizing that while something like a.b.c.d is simple to write, what it causes the ORM layer to do as it is evaluated is not. As a general rule I always go with the simplest possible approach to begin, and then write optimized queries in areas where it makes sense/where it is obvious that the simple approach will not scale.


I'd say, one should use the appropriate tool for different tasks.

E.g., for CRUD operations, ORM frameworks like Hibernate can speed up development and it will perform well enough. Sometimes you need to do some necessary tweaks to achieve acceptable performance. I'm not sure, your task (what took 50 sec with Hibernate) could not be done properly with Hibernate, because you did not provide us with the details.

On the other hand, for example bulk operations involving hundreds of thousands of records is not the type of task you'd expect Hibernate will do without significant performance penalty.


As it was mentioned already, ORM is only a tool and you can use it eiter good or bad.

One of the most typical performance problems in ORMs is 1+N queries problem. It is caused by loading additional objects for each of objects from the list. This is caused by eager fetch of 1-to-n-relation entities for each element on list, the dealing is using HQL queries, specifying fields in projection or marking fetching 1-to-n relations to lazy.

Any time, you must exactly know what the ORM is doing in order to achieve good performance. Not understanding what operations are done in background is a way to disaster (slow, buggy and hard to analyze code because of unnecessary and wrongly written work-arounds).


I'm with Petar from your comments regarding the lazy fetching. Say you have an html table filled fields from object a.b.c.d. You could find your framework round-tripping the database thousands of times(possibly many more) . The disadvantage of ORM in this case is you have to read the documentation thoroughly. Most frameworks support disabling lazy fetching and many even support adding your own processing logic to bind the data set.

The net out is that almost any ORM is almost undoubtedly better than anything you are going to write yourself. You will find yourself saddled with maintaining huge libraries of boilerplate or worse writing the same code over and over again.


We are currently investigating to switch from our own data store layer with clean separation of transfer objects and data access objects to JPA. We used a generator to create the TOs, the DAOs and the SQL DDL as well from some documentation in docbook format. By this all of our stuff from documentation, the database structure and the generated Java classes where always in sync with a good documentation of the database itself.

What we discovered so far by using JPA:

  1. Foreign key references cannot be used for imports, some special queries and so on because they must not be placed in a managed entity. JPA only allows the target class there.
  2. Access to some user session scope is difficult upto impossible. We still have no clue how to get the users id into the column 'userWhoLastMadeAnUpdate' in some PrePersist method.
  3. Something expected to be quite easy with an ORM, namely "class mapping" does not work at all. We are using HalDateTime (http://sourceforge.net/projects/haldatetime/) internally. Especially in the client. Mapping it with JPA directly is not possible although HalDateTime supports it. Due to JPA restrictions we have to use two fields in the entity.
  4. JPA uses either one XML file to describe the mapping. So you have to look at least into two files to even understand the relationship between the Java class and the database. And the XML file becomes huge for large applications.
  5. Alternatively ORMs provide annotations in the Java class itself. So its easier to learn and understand the relationship. But it forces you to see all that database stuff in the client layer (which completely breaks a proper layering).
  6. You will have to restrict yourself to stay as close to a clean database structure as anyhow possible. Otherwise you will for sure end up with a mess of queries and statements by the ORM.
  7. Use an ORM which provides a query language which is close to SQL itself (JPA seems quite acceptable here). An ORM induced language makes supporting a large application really expensive.
0

精彩评论

暂无评论...
验证码 换一张
取 消