tags:

views:

407

answers:

3

Say I have the following Hibernate-mapped class:

public class ClassA {       
   @OneToMany(fetch=EAGER)
   private List<ClassB> bList;
}

When I read an object of ClassA from a Hibernate session, the bList field is initialized with a PersistentList object, as expected.

I find myself with a requirement where in situations where the list is empty, I need Hibernate to initialize the bList field to null, rather than with an empty PersistentList. In theory, Hibernate has the information it needs to do this, since the fetch on the list is eager. The problem is that according to section 6.1 of the Hibernate docs:

Due to the underlying relational model, collection-valued properties do not support null value semantics. Hibernate does not distinguish between a null collection reference and an empty collection.

This makes perfect sense, but I'm hoping someone can come up with a cunning ruse to overcome this limitation. I'm thinking perhaps some listener/callback mechanism might allow me to replace empty lists with null references.

+2  A: 

Have you tried to check in the getbList() method? You could do:

if(bList.isEmpty()) 
    return null;
return bList;

Hibernate will always create an object for your references, but you are allowed to control the data inside of the getter and setters. If the list has 0 elements you can always return null.

amischiefr
I think this may end up being the simplest solution, yes
skaffman
A: 

I'm curious why you consider this a "limitation' - does a null bList actually have a different meaning to your application than an empty bList?

I think that in most areas, a null collection and an empty collection have the same semantic meaning, which I would guess is why the Hibernate developers sought to limit Hibernate to only using one. Doesn't make much sense to always check if (bList == null || bList.isEmpty) if the two always end up meaning the same thing.

matt b
It most situations, you'd be correct, but the clients of this particular object model distinguish between null and empty, and I have no control over that.
skaffman
+1  A: 

For handling in your code the obvious way is in the getter, however that doesn't help you if you want to evaluate it in HQL.

Two ideas:

  • A constructor that sets it to NULL if empty.
  • A @PostLoad / @PostConstruct method that does the same.
Damo
Ah, I wasn't aware of @PostLoad, I'm liking that. How does it interact with @PostConstruct?
skaffman