views:

222

answers:

3

What it says on the tin; I want to modify a collection in Hibernate without forcing the collection to load, since it is a large volume of data (~100,000 records, monotonically increasing).

Right now, I add an element to this list by calling getEvents ().add (newEvent) which, of course, causes events to be populated.

Here's the mapping:

<bag name = "events" inverse = "true" cascade = "all-delete-orphan"
 order-by = "event_date desc" lazy = "true">
  <key>
<column name = "document_id" length = "64" not-null = "true" />
  </key>
  <one-to-many class = "EventValue" />
</bag>

How should I be doing this?

+3  A: 

One way to accomplish this would be to create a bidirectional association between the parent object (let's call it Parent) and the Event and configure your hibernate mappings such that the relationship is managed by Event.

To accomplish this, your Hibernate mappings would look something like:

<class name="Parent"...>
    ...
    <bag name="events" lazy="true" inverse="true"...>...</bag>
    ...
</class>

<class name="Event"...> 
    <many-to-one name="parent">
    ...
</class>

And your code would look something:

myEvent.setParent(parentObject);
eventDao.save(myEvent);

Hope this helps. Good luck.

blahspam
What side effects does that have in terms of working with the object, otherwise?
Chris R
It really depends on how and when you are using the results of Parent.getEvents(). You may be required to re-fetch the Parent and/or expire it from the cache... but in most typical cases you won't need to do anything special and it will "just work"
blahspam
A: 

Hibernate only lazy loads the proxied object (the Events) when it encounters a getter. You could try using a public field reference instead of the getter for Events eg.

bean.events.add()

rather than

bean.getEvents().add()
Damo
A: 

Just insert the Event.

for example :

@Entity
public Document
{
    @ManyToOne
    Set<Event> events;

    public void addEvent( Event event )
    {
     events.add( event )
    }

}


@Entity
public Event
{
    @id
    private long id;

    @OneToMany
    private Document  doc;

    ....
}

Option that may read all of the events:

document.add( event );
update( document );

Option that wouldn't touch the collection:

    event = new Event();
    event.setDocument( document );
    insert( event );

Then when you call document.getEvents() it would query and get the new event also. The only issue is if the collection has already been read and then you insert the event by option 2. In that case the getEvents() would not include the new event since the collection has already been read.

ccclark
Basically what blahspam was said.
ccclark