-->
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.  [ 9 posts ] 
Author Message
 Post subject: Session.save() nested within PostUpdateEventListener doesn't
PostPosted: Wed Dec 07, 2005 7:21 pm 
Newbie

Joined: Thu Jun 16, 2005 6:44 pm
Posts: 6
Location: Salt Lake City, UT
I'm trying to create new objects from within a PostUpdateEventListener. The issue is that the new Object being saved, does indeed make it's way to a AbstractSaveEventListener, but the SQL is never generated and sent to the database until another statement forces a flush.

I tried setting

<prop key="hibernate.transaction.flush_before_completion">true</prop>

but doing that alone does not ever generate and send the SQL. I need to explicitly do a Session.find() or something of the sort.

Is saving a new object inside of an EventListener a big NoNo? If so, what is the recommended best practice?

(see below for sample )
-------------------------- Something Like This ------------------------------------------
public class ChangeLogListener implements PostUpdateEventListener {
public void onPostUpdate(PostUpdateEvent event) {
MappedObject newObj = new MappedObject();
event.getSession().save( newObj );
}
}


Top
 Profile  
 
 Post subject: Create a new Session on the same connection
PostPosted: Thu Dec 08, 2005 12:48 pm 
Newbie

Joined: Thu Jun 16, 2005 6:44 pm
Posts: 6
Location: Salt Lake City, UT
Instead of calling event.getSession().save( o ) to save the new object, call saveNewObjectFromWithinEventListener( o ) as implemented below. It will obtain the SessionFactory from the current Session and open a new Session on top of the same connection - this new Session can safely be flushed. This mechanism works fine with Transactions, specifically when using the JDBC transactions as managed with Spring's HibernateTransactionManger.

Code:
    private void saveNewObjectFromWithinEventListener( Object o, PostUpdateEvent event ) {
       // Since we are already in the flush logic of our current session,
       // do our changelog work inside of a separate session
       SessionFactory factory = event.getSession().getFactory();
       Session session2 = factory.openSession( event.getSession().connection());
       session2.save( o );
       session2.flush();
    }
[/code]


Top
 Profile  
 
 Post subject: with 3.1.2?
PostPosted: Thu Feb 23, 2006 11:55 am 
Beginner
Beginner

Joined: Fri Jul 08, 2005 8:55 pm
Posts: 37
Hi

have you managed to do the same thing with Hibernate 3.1.2?

PostUpdateEvent does not have a getSession() method anymore...

How did you manage?

Many thanks

Benoit


Top
 Profile  
 
 Post subject: Doh
PostPosted: Thu Feb 23, 2006 1:15 pm 
Newbie

Joined: Thu Jun 16, 2005 6:44 pm
Posts: 6
Location: Salt Lake City, UT
Benoit, I'm not currently working on the project that I wrote that snippet of code for, so I haven't had to maintain it across releases of Hibernate.

Are you using Spring with Hibernate? If so, I would recommend trying to wire the SessionFactory to the EventListener using Spring IoC. Then it can just call getSession() on that SessionFactory rather than on the PostUpdateEvent.

Hopefully doing so won't result in any sort of chicken and the egg configuration issues.

If you're not using Spring, then I guess you can do the same thing in code rather than declaratively.

LMK if you need more help or suggestions.


Top
 Profile  
 
 Post subject: thanks
PostPosted: Thu Feb 23, 2006 1:24 pm 
Beginner
Beginner

Joined: Fri Jul 08, 2005 8:55 pm
Posts: 37
Hi darren

Thanks for your reply.

I am using JBoss and was hoping that the event would be able to give me the session in which it happened (as it used in 3.0.5) but it looks like I will have to go the SessionFactory (JNDI call) and ask for the getCurrentSession()...

Seems to be more convoluted and less efficient but there must be a good reason.

Thanks!

Benoit


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 23, 2006 1:33 pm 
Newbie

Joined: Thu Jun 16, 2005 6:44 pm
Posts: 6
Location: Salt Lake City, UT
Cool - will you be sure to post your solution so this thread is current ( at least for JBoss using JNDI ...)

Thanks to you, too.


Top
 Profile  
 
 Post subject: no prob
PostPosted: Thu Feb 23, 2006 1:46 pm 
Beginner
Beginner

Joined: Fri Jul 08, 2005 8:55 pm
Posts: 37
Sure...

Here is a solution that works:

Code:
    private void saveNewObjectFromWithinEventListener( Object myObject ) {
        try {
            InitialContext ctx = new InitialContext();
            SessionFactory factory = (SessionFactory) ctx.lookup("java:/hibernate/SessionFactory");
            factory.getCurrentSession().save(myObject);
        } catch (NamingException e) {
            throw new HibernateException(e);
        }
}


Hope this helps.

Benoit

PS: any rating welcome!!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 12:26 pm 
Beginner
Beginner

Joined: Mon Sep 12, 2005 3:27 am
Posts: 48
Code:
  private void saveNewObjectFromWithinEventListener( Object myObject ) {
        try {
            InitialContext ctx = new InitialContext();
            SessionFactory factory = (SessionFactory) ctx.lookup("java:/hibernate/SessionFactory");
            factory.getCurrentSession().save(myObject);
        } catch (NamingException e) {
            throw new HibernateException(e);
        }

Is this really working for somebody ? If i try this solution in Jboss 4.0.5 EJB3 RC9 inside a post-update-listener, my fresh created Entity will never get persisted in the database when i invoke
Code:
factory.getCurrentSession().save(myObject);

Yes i checked, my update-listener is really invoked within jboss, factory is bound and found in jndi - only the persist does nothing, not even an exception.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 21, 2006 12:15 pm 
Beginner
Beginner

Joined: Mon Sep 12, 2005 3:27 am
Posts: 48
It seems that i have to explicitly flush()the session, then the entity gets persisted out of the listener


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 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.