11

I have a component mapped using Hibernate. If all fields in the component in the database are null, the component itself is set to null by hibernate. This is the expected behavior and also what I need.

The problem I have, is that when I add a bag to that component, the bag is initialized to an empty list. This means the component has a non null value... resulting in the component being created.

Any idea how to fix this?

<class name="foo.bar.Entity" table="Entity">
<id name="id" column="id">
    <generator class="native" />
</id>

<property name="departure" column="departure_time" />
<property name="arrival" column="arrival_time" />

<component name="statistics">
    <bag name="linkStatistics" lazy="false" cascade="all" >
        <key column="entity_id" not-null="true" />
        <one-to-many class="foo.bar.LinkStatistics" />
    </bag>

    <property name="loggedTime" column="logged_time" />

    ...
</component>

A criteria with Restirctions.isNull("statistics") does return the expected values.

Jurgen Hannaert
  • 973
  • 10
  • 22

3 Answers3

1

The basic problem here is that Hibernate can't distinguish between null collections and empty collections, so it treats them both as empty: non-null.

I suggest you change your Statistics component to an real entity instead. Then your foo.bar.Entity class has a reference, which can be null. This is not ideal because you'll have to create another table to store the Statistics entity, but if you want the null vs empty semantic distinction, that's a way to get it.

sharakan
  • 6,821
  • 1
  • 34
  • 61
  • Correct. The concept of collection doesn't really exist in the RDBMS so Hibernate (or any ORM) has to do *something*. – Joshua Davis Feb 24 '12 at 22:00
0

I can't verify this but here's an idea:

public void setListProperty(List list) {
  if (list == null || list.size() == 0) {
    this.listProperty = null;
  } else {
    this.listProperty = list;
  }
}

Obviously not ideal but might be a workaround for you...

Mark Pope
  • 11,244
  • 10
  • 49
  • 59
  • Does this approach really works for you? From my experience such tricks in setters lead to exception "another collection is already associated with session" in Hibernate (because Hibernate will remember the empty collection it intended to associate with parent entity). So the code above will work when entity became detached (session it was loaded with was closed), but will fail otherwise. Using `null` in getter is much better :) – dma_k Nov 12 '11 at 12:58
0

Maybe this can help .it doesn't solve the problem of distinguishing between null and empty bag but it's a workaround. As you might know you can introduce an interceptor to your session that can intercept in certain actions like saving or updating entities then you can use this interceptor to check the state of your component and if it is empty make it null again so that hibernate won't save empty values. here's the docs.

Beatles1692
  • 5,214
  • 34
  • 65