-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: OR-Mapping Limitations of Hibernate?
PostPosted: Sat Sep 05, 2009 11:44 am 
Newbie

Joined: Sat Sep 05, 2009 11:30 am
Posts: 2
Hi everyone!

We use hibernate for some months now and as I still struggle with one very principle question which turns out to be hard to google, so I just registered here to ask the "Pro"s right away ;-)

As I understand it so far, you can't really design straight forward Java classes as you would do without persistence and then just pass them (or better: their instances) to hibernate and say: "Go persist it!". Things like collections and inheritence need some special treatment and constraints in hibernate, as it turned out.

So instead you have to create Hibernate-compatible "entity classes" (that's how we call them) which use only Java constructs that Hibernate can handle and that your actual program/classes have to be built around.

So for me, the question came up:
Exactely what Java constructs can Hibernate handle in its OR-Mapping and what not?

By "handle", I mean: create appropriate tables, save the object and load it again, ensuring full referential integrity int the object tree, etc.

I already figured out / read about some points and would like them to be validated / explained / disproven if possible.
Some other points are still unclear (because hard to google, tbh).

Another note beforehand: It's not as simple as to say "go try and you will see."
The whole posting is about if there is some Annotation / configuration / custom type definition / etc that hibernate provides (and that is maybe not so easy to find for a newbie like me) that makes these things possible even if a simple test says it doesn't work.



Limitations I know so far:

Collections
- Hibernate can only persist collections by the type of the class field that references them and the field type must be a collection Interface (Like java.util.List.class etc).
So you can't write a class field like
Code:
private ArrayList<String> myStringList;

- afaik, Hibernate can't handle nested collections (Like HashMap<Integer, HashMap<String, String>> for example)
- Hibernate always replaces the actual type of the Collection by a compatible collection type of its own, so the actual type is lost/not reliable on by the programm (behaviour- and reflection-wise)


Generalisation
- Hibernate can't handle a class field that is just of type Object
So for example this:
Code:
private Object anyReference = new MyPersistentClass();

Won't be handleable by Hibernate. Is that correct?
(note: yes i know that you "should" not do this in general. I of course don't do this in general. It's more about the question: can it be handled without a hitch if the rare case occurs that it has to be done for some reason)


Unclear Java Features:

Class field with superclass type
Say I have the following class field:
Code:
private MyPersistentSuperClass someReference;

Can Hibernate handle the actual instance that this field will reference no matter what concrete type it will be during runtime?
For example:
Code:
someReference = new MyPersistentSubClass();
or
Code:
someReference = new MyOtherPersistentSubClass();

etc...


Class field with interface type
Same as the point above for Interfaces:
If I have a "private MyInterface someReference;", can Hibernate handle instances of persistent classes that are referenced by this field?
Like, again:
Code:
someReference = new MyPersistentSubClass(); // MyPersistentSubClass implements MyInterface


Arrays
Can Hibernate handle multi-dimensional arrays?
Like:
Code:
private MyPersistentSubClass[][][] my3d = ...
?

And what about referential integrity after loading when sub-arrays of multi-dimensional arrays are referenced elsewhere?
Like:
Code:
private MyPersistentSubClass[][] my2d = my3d[0]

So after saving and loading both arrays (to and from the db of course, not only the cache), will my2d and my3d[0] still point to the SAME two-dimensional array instance?


Inner Classes
Can instances of inner class (which reference an instance of their outer class) be handled by hibernate?

Inner Static Classes
Can instances of inner static class be handled by hibernate?


Hm. I'm not sure if these are all points. At least for now I can't think of anything else...

Thanks for answers!


Top
 Profile  
 
 Post subject: Re: OR-Mapping Limitations of Hibernate?
PostPosted: Sat Sep 05, 2009 8:53 pm 
Beginner
Beginner

Joined: Fri Oct 28, 2005 10:46 am
Posts: 37
I'll take a shot at some of these.

Quote:
As I understand it so far, you can't really design straight forward Java classes as you would do without persistence and then just pass them (or better: their instances) to hibernate and say: "Go persist it!". Things like collections and inheritence need some special treatment and constraints in hibernate, as it turned out.

So instead you have to create Hibernate-compatible "entity classes" (that's how we call them) which use only Java constructs that Hibernate can handle and that your actual program/classes have to be built around.

I would say just the opposite. When I'm designing code, I write the classes first and go map them in Hibernate after I'm satisfied with the class design. For the most part--given well-designed classes--Hibernate can do its job with little to no intrusion.

Quote:
So for me, the question came up:
Exactely what Java constructs can Hibernate handle in its OR-Mapping and what not?

By "handle", I mean: create appropriate tables, save the object and load it again, ensuring full referential integrity int the object tree, etc.

That's a very broad question. My answer would be that Hibernate can handle virtually anything you would write in a production Java app.

[...]
Quote:
Limitations I know so far:

Collections
- Hibernate can only persist collections by the type of the class field that references them and the field type must be a collection Interface (Like java.util.List.class etc).
So you can't write a class field like
Code:
private ArrayList<String> myStringList;

That's correct, but what you're suggesting is a very poor practice anyway. For collections in particular and inheritance hierarchies in general, you should always default to using interface types and only refer to objects by their concrete types when you have a clear need for it. Therefore, Hibernate is designed specifically to handle the preferred method of working with collections: typing them as Collection, List, Map, or Set.

Quote:
- afaik, Hibernate can't handle nested collections (Like HashMap<Integer, HashMap<String, String>> for example)

To my knowledge, this is correct; however it's not much of a limitation because most of the time you'll find that if you think you need a collection of collections, there's actually an intermediate entity that you should create to represent the relationship and contain information about it, not to mention giving it better organization and making it easier to understand and work with.

Quote:
- Hibernate always replaces the actual type of the Collection by a compatible collection type of its own, so the actual type is lost/not reliable on by the programm (behaviour- and reflection-wise)

Again, you should never care that something is an ArrayList, only that it's a List. That removes this problem.

Quote:
Generalisation
- Hibernate can't handle a class field that is just of type Object
So for example this:
Code:
private Object anyReference = new MyPersistentClass();

Won't be handleable by Hibernate. Is that correct?
(note: yes i know that you "should" not do this in general. I of course don't do this in general. It's more about the question: can it be handled without a hitch if the rare case occurs that it has to be done for some reason)

No, this is incorrect. Hibernate cares little about the declared type of the variable, though you'd have to take an extra configuration step to inform Hibernate what the "type" of this field is because it won't be able to figure it out on its own. Besides that, as long as the persistent instance is assignable to it, everything's fine, and of course anything is assignable to Object.

Quote:
Unclear Java Features:

Class field with superclass type
Say I have the following class field:
Code:
private MyPersistentSuperClass someReference;

Can Hibernate handle the actual instance that this field will reference no matter what concrete type it will be during runtime?
For example:
Code:
someReference = new MyPersistentSubClass();
or
Code:
someReference = new MyOtherPersistentSubClass();

etc...

Class field with interface type
Same as the point above for Interfaces:
If I have a "private MyInterface someReference;", can Hibernate handle instances of persistent classes that are referenced by this field?
Like, again:
Code:
someReference = new MyPersistentSubClass(); // MyPersistentSubClass implements MyInterface

Absolutely. As I said before, Hibernate cares little about the declared type of a property. It just saves/loads what's actually there, and as long as the object it persists is assignable to the variable that's intended to hold it, everything's fine.

Quote:
Arrays
Can Hibernate handle multi-dimensional arrays?
Like:
Code:
private MyPersistentSubClass[][][] my3d = ...
?

I don't believe so. It's like the collection of collections thing.

Quote:
And what about referential integrity after loading when sub-arrays of multi-dimensional arrays are referenced elsewhere?
Like:
Code:
private MyPersistentSubClass[][] my2d = my3d[0]

So after saving and loading both arrays (to and from the db of course, not only the cache), will my2d and my3d[0] still point to the SAME two-dimensional array instance?

Problems like this are probably part of the reason that Hibernate doesn't support things like multi-dimensional arrays and collections of collections, not to mention that these things often indicate a poorly-designed object model and tend not to make it into production code, so there's little demand for these features.

On the referential integrity front, the second level cache, which I assume you were talking about, has nothing to do with the discussion. Objects are "dehydrated" before being stored in the cache. The actual object instances are not stored, and when an object is retrieved from the cache, you always get a new, separate instance.

There is, however a first-level cache--the Session--which ensures that if you load the same entity twice, you'll get the same instance both times.

Quote:
Inner Classes
Can instances of inner class (which reference an instance of their outer class) be handled by hibernate?

Inner Static Classes
Can instances of inner static class be handled by hibernate?

Inner classes, no. Static nested classes, which technically are not inner classes, yes. To map a class in Hibernate, it must be instantiable on its own, which an inner class is not.

Quote:
Hm. I'm not sure if these are all points. At least for now I can't think of anything else...

Thanks for answers!

One final note: for the situations you mentioned that Hibernate doesn't actually support, you can always write a custom UserType to map any kind of data structure you want to the database.

HTH

Ryan


Top
 Profile  
 
 Post subject: Re: OR-Mapping Limitations of Hibernate?
PostPosted: Sun Sep 06, 2009 6:40 pm 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Quote:
When I'm designing code, I write the classes first and go map them in Hibernate after I'm satisfied with the class design. For the most part--given well-designed classes--Hibernate can do its job with little to no intrusion.


I agree. I typically build an object model, and then do the mapping. I always like to get onto projects early, so I can create a database schema based on my object model, before the database admins get in there and mess everything up. Unfortunately, most projects tend to end up being 'meet in the middle' nightmares.

-Cameron McKenzie

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject: Re: OR-Mapping Limitations of Hibernate?
PostPosted: Tue Sep 08, 2009 2:26 pm 
Newbie

Joined: Sat Sep 05, 2009 11:30 am
Posts: 2
Thanks very much for your replies!

The answers are of very high quality imo and are perfectly what i hoped for.
Especially things like that that link to the UserType Interface :-).

I also understand what you mean with poorly-designed object model.
Although I kind of disagree that multidimensional arrays are poor design ;-).
Same goes for nested collections or concrete Collection classes in some (granted rare) cases.
Still, for "most" cases I agree, of course.

Anyway, thanks again =).


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.