You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by g kuczera <gk...@gmail.com> on 2016/02/24 21:23:36 UTC

Calling method after CommitAfter call

Hi guys,
I embedded the ApplicationSubmitForm (component) in my Page. If it is
successfully validated, the onSuccessFromNewApplicationForm method is
called:

private Set<FormSubmitObserver> observers;

  @CommitAfter
  public void onSuccessFromNewApplicationForm() {

    Application application = new Application();
    application.setStatus(/* some value */);
    application.setRegistrationDate(new Date());

    notifyObservers(application, true);
  }

One of the observers - there is a field *observers*, which is a set - sends
an event to the mailing server. In 99% cases it works fine, but sometimes
the second application (on the different server), while checking if an
application indicated by the given id exists, does not find the record.
There is nothing like that in the database yet.

It looks that the above module is badly designed. It does not matter that
there is the CommitAfter annotation, if I call the methods which assume
that everything is commited from within the commiting method.

Am I right?

Re: Calling method after CommitAfter call

Posted by Kalle Korhonen <ka...@gmail.com>.
On Wed, Feb 24, 2016 at 12:27 PM, g kuczera <gk...@gmail.com> wrote:

> Sorry for not editing the post properly, I accidentally sent it by pressing
> the space few times (first time using the fullscreen editing on gmail).
>
> So, the question is if the hibernate Interceptor is the way to go? Do you
> have any other idea how to be 100% sure that my method from observer will
> be called after committing the changes?
>

The obvious choice is to manually commit the transaction, then notify the
observers. @CommitAfter is fine for simple cases but if the transaction is
rolled back, it doesn't allow you to react to it. If you still prefer
annotation, you could try out
https://github.com/satago/tapestry-jpa-transactions that support pre/after
commit hooks.

Kalle



> 2016-02-24 21:23 GMT+01:00 g kuczera <gk...@gmail.com>:
>
> > Hi guys,
> > I embedded the ApplicationSubmitForm (component) in my Page. If it is
> > successfully validated, the onSuccessFromNewApplicationForm method is
> > called:
> >
> > private Set<FormSubmitObserver> observers;
> >
> >   @CommitAfter
> >   public void onSuccessFromNewApplicationForm() {
> >
> >     Application application = new Application();
> >     application.setStatus(/* some value */);
> >     application.setRegistrationDate(new Date());
> >
> >     notifyObservers(application, true);
> >   }
> >
> > One of the observers - there is a field *observers*, which is a set -
> > sends an event to the mailing server. In 99% cases it works fine, but
> > sometimes the second application (on the different server), while
> checking
> > if an application indicated by the given id exists, does not find the
> > record. There is nothing like that in the database yet.
> >
> > It looks that the above module is badly designed. It does not matter that
> > there is the CommitAfter annotation, if I call the methods which assume
> > that everything is commited from within the commiting method.
> >
> > Am I right?
> >
> >
> >
>

Re: Calling method after CommitAfter call

Posted by g kuczera <gk...@gmail.com>.
Sorry for not editing the post properly, I accidentally sent it by pressing
the space few times (first time using the fullscreen editing on gmail).

So, the question is if the hibernate Interceptor is the way to go? Do you
have any other idea how to be 100% sure that my method from observer will
be called after committing the changes?

2016-02-24 21:23 GMT+01:00 g kuczera <gk...@gmail.com>:

> Hi guys,
> I embedded the ApplicationSubmitForm (component) in my Page. If it is
> successfully validated, the onSuccessFromNewApplicationForm method is
> called:
>
> private Set<FormSubmitObserver> observers;
>
>   @CommitAfter
>   public void onSuccessFromNewApplicationForm() {
>
>     Application application = new Application();
>     application.setStatus(/* some value */);
>     application.setRegistrationDate(new Date());
>
>     notifyObservers(application, true);
>   }
>
> One of the observers - there is a field *observers*, which is a set -
> sends an event to the mailing server. In 99% cases it works fine, but
> sometimes the second application (on the different server), while checking
> if an application indicated by the given id exists, does not find the
> record. There is nothing like that in the database yet.
>
> It looks that the above module is badly designed. It does not matter that
> there is the CommitAfter annotation, if I call the methods which assume
> that everything is commited from within the commiting method.
>
> Am I right?
>
>
>

Re: Calling method after CommitAfter call

Posted by g kuczera <gk...@gmail.com>.
Guys, I forgot to tell you that since applying the
"HibernateSessionManager.commit()" everything works like a charm. It looks
that it was indeed the problem with synchronisation.

2016-02-26 13:14 GMT+01:00 Thiago H de Paula Figueiredo <th...@gmail.com>
:

> On Fri, 26 Feb 2016 07:54:47 -0300, g kuczera <gk...@gmail.com> wrote:
>
> But I feel quite ashamed of this solution. It's like forcing the inner
>> mechanism of Tapestry's Hibernate Wrapper (or even the Hibernate by
>> itself,
>> it's flow) to commit the thing before it is appropriate.
>>
>
> I disagree. Tapestry-Hibernate is a thin wrapper to begin with. What
> you're doing is very normal usage of both Tapestry and Hibernate.
>
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: Calling method after CommitAfter call

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Fri, 26 Feb 2016 07:54:47 -0300, g kuczera <gk...@gmail.com> wrote:

> But I feel quite ashamed of this solution. It's like forcing the inner
> mechanism of Tapestry's Hibernate Wrapper (or even the Hibernate by   
> itself,
> it's flow) to commit the thing before it is appropriate.

I disagree. Tapestry-Hibernate is a thin wrapper to begin with. What  
you're doing is very normal usage of both Tapestry and Hibernate.

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Calling method after CommitAfter call

Posted by Dmitry Gusev <dm...@gmail.com>.
Hi,

The tapestry-jpa-transactions module doesn't use any JPA interceptors, its
before/after commit hooks are implemented in the same advice that opens and
commits transactions for @CommitAfter. In theory you could do the same for
Hibernate too.

But in your case you could extract business logic that deals with
applicationDao to another service's method, put @CommitAfter annotation on
that method, and you're done, i.e.:

public void onFormSubmit(Object observable, Object o)
{
    Application application = (Application) o;
    applicationService.updateUser(application, user);

    // transaction will be committed here
    publisher.sendApplicationSubmittedMessage(
        user.getId(), application.getId());
}

public interface ApplicationService
{
    @CommitAfter
    void updateUser(Application application, User user);
}

On Fri, Feb 26, 2016 at 1:54 PM, g kuczera <gk...@gmail.com> wrote:

> Thanks for the comprehensive answer. Right now I am testing the
> HibernateSessionManager usage.
> I added it as the field in my page:
>   @Inject
>   private HibernateSessionManager hibernateSessionManager;
>
> and then I commit it in the onFormSubmit method:
>
>   public void onFormSubmit(Object observable, Object o) {
>     Application application = (Application) o;
>     application.setUser(user);
>     applicationDao.save(application);
>     hibernateSessionManager.commit();
>
>     publisher.sendApplicationSubmittedMessage(user.getId(),
> application.getId());
>   }
>
> But I feel quite ashamed of this solution. It's like forcing the inner
> mechanism of Tapestry's Hibernate Wrapper (or even the Hibernate by itself,
> it's flow) to commit the thing before it is appropriate.
>
> However switching from Hibernate to JPA is not an option for me and
> Interceptors, if I understand them well, seems like an overhead.
>
> 2016-02-25 15:52 GMT+01:00 Thiago H de Paula Figueiredo <
> thiagohp@gmail.com>
> :
>
> > On Thu, 25 Feb 2016 11:30:44 -0300, g kuczera <gk...@gmail.com>
> wrote:
> >
> > In the end I gave up implementing the JPA, because I do not want to mix
> >> these two different approaches (Hibernate sessions and JPA).
> >>
> >
> > The suggestion would be using JPA instead of Hibernate, not mixing them.
> >
> > So I have one questions: where do I find the HibernateSessionManager
> >> implementation?
> >>
> >
> >
> >
> https://github.com/apache/tapestry5/blob/master/tapestry-hibernate-core/src/main/java/org/apache/tapestry5/internal/hibernate/HibernateSessionManagerImpl.java
> >
> > It looks that I can't use regular
> >> session.getTransaction().commit() becase it gives me *Transaction not
> >> successfully started *error.
> >>
> >
> > In this case, you should start the transaction manually, just as you
> > commit it manually.
> >
> > I have been reading about these (hibernate and tapestry) machanisms and
> it
> >> looks that every thread has it's own session, which is being managed by
> >> HibernateSessionManager. I am not pretty sure how to obtain that
> manager,
> >> to safely commit the transaction.
> >>
> >
> > It's a Tapestry-IoC service, so you can @Inject it in your pages or have
> > it automatically injected into your services' constructors.
> >
> >
> > --
> > Thiago H. de Paula Figueiredo
> > Tapestry, Java and Hibernate consultant and developer
> > http://machina.com.br
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>



-- 
Dmitry Gusev

AnjLab Team
http://anjlab.com

Re: Calling method after CommitAfter call

Posted by g kuczera <gk...@gmail.com>.
Thanks for the comprehensive answer. Right now I am testing the
HibernateSessionManager usage.
I added it as the field in my page:
  @Inject
  private HibernateSessionManager hibernateSessionManager;

and then I commit it in the onFormSubmit method:

  public void onFormSubmit(Object observable, Object o) {
    Application application = (Application) o;
    application.setUser(user);
    applicationDao.save(application);
    hibernateSessionManager.commit();

    publisher.sendApplicationSubmittedMessage(user.getId(),
application.getId());
  }

But I feel quite ashamed of this solution. It's like forcing the inner
mechanism of Tapestry's Hibernate Wrapper (or even the Hibernate by itself,
it's flow) to commit the thing before it is appropriate.

However switching from Hibernate to JPA is not an option for me and
Interceptors, if I understand them well, seems like an overhead.

2016-02-25 15:52 GMT+01:00 Thiago H de Paula Figueiredo <th...@gmail.com>
:

> On Thu, 25 Feb 2016 11:30:44 -0300, g kuczera <gk...@gmail.com> wrote:
>
> In the end I gave up implementing the JPA, because I do not want to mix
>> these two different approaches (Hibernate sessions and JPA).
>>
>
> The suggestion would be using JPA instead of Hibernate, not mixing them.
>
> So I have one questions: where do I find the HibernateSessionManager
>> implementation?
>>
>
>
> https://github.com/apache/tapestry5/blob/master/tapestry-hibernate-core/src/main/java/org/apache/tapestry5/internal/hibernate/HibernateSessionManagerImpl.java
>
> It looks that I can't use regular
>> session.getTransaction().commit() becase it gives me *Transaction not
>> successfully started *error.
>>
>
> In this case, you should start the transaction manually, just as you
> commit it manually.
>
> I have been reading about these (hibernate and tapestry) machanisms and it
>> looks that every thread has it's own session, which is being managed by
>> HibernateSessionManager. I am not pretty sure how to obtain that manager,
>> to safely commit the transaction.
>>
>
> It's a Tapestry-IoC service, so you can @Inject it in your pages or have
> it automatically injected into your services' constructors.
>
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: Calling method after CommitAfter call

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Thu, 25 Feb 2016 11:30:44 -0300, g kuczera <gk...@gmail.com> wrote:

> In the end I gave up implementing the JPA, because I do not want to mix
> these two different approaches (Hibernate sessions and JPA).

The suggestion would be using JPA instead of Hibernate, not mixing them.

> So I have one questions: where do I find the HibernateSessionManager
> implementation?

https://github.com/apache/tapestry5/blob/master/tapestry-hibernate-core/src/main/java/org/apache/tapestry5/internal/hibernate/HibernateSessionManagerImpl.java

> It looks that I can't use regular
> session.getTransaction().commit() becase it gives me *Transaction not
> successfully started *error.

In this case, you should start the transaction manually, just as you  
commit it manually.

> I have been reading about these (hibernate and tapestry) machanisms and  
> it looks that every thread has it's own session, which is being managed  
> by
> HibernateSessionManager. I am not pretty sure how to obtain that manager,
> to safely commit the transaction.

It's a Tapestry-IoC service, so you can @Inject it in your pages or have  
it automatically injected into your services' constructors.

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Calling method after CommitAfter call

Posted by g kuczera <gk...@gmail.com>.
In the end I gave up implementing the JPA, because I do not want to mix
these two different approaches (Hibernate sessions and JPA).

So I have one questions: where do I find the HibernateSessionManager
implementation? It looks that I can't use regular
session.getTransaction().commit() becase it gives me *Transaction not
successfully started *error.

Here is my onFormSubmit method:

  public void onFormSubmit(Object observable, Object o) {
    Application application = (Application) o;
    applicationDao.save(application);

    if(!applicationDao.getSession().getTransaction().wasCommitted()) {
        applicationDao.getSession().getTransaction().commit();
        applicationDao.getSession().beginTransaction();
        log.info("Commiting the transaction!");
    } else {
        log.info("Do not commiting the transaction!");
    }

    caseId = application.getApplicationCase().getId();

    publisher.sendApplicationSubmittedMessage(user.getId(),
ipSource.getIpAddress(), caseId, application.getId());
  }

I have been reading about these (hibernate and tapestry) machanisms and it
looks that every thread has it's own session, which is being managed by
HibernateSessionManager. I am not pretty sure how to obtain that manager,
to safely commit the transaction.

Right now I am trying to get that manager and then call the commit.

2016-02-25 8:57 GMT+01:00 g kuczera <gk...@gmail.com>:

> But I think a JPA hook would be a better choice. The Interceptor hooks
>> happen for *all* the transactions in your SessionFactory, and JPA hooks are
>> more fine-grained.
>
> I am not really into JPA thing, but if I understand well I have to add the
> whole new configuration (in AppModule), as stated here:
> https://tapestry.apache.org/integrating-with-jpa.html
>
> All my classes are Daos and Dtos which uses the org,hibernate.Session (at
> least the Daos).
>
> 2016-02-24 23:55 GMT+01:00 Thiago H de Paula Figueiredo <
> thiagohp@gmail.com>:
>
>> On Wed, 24 Feb 2016 19:33:13 -0300, g kuczera <gk...@gmail.com> wrote:
>>
>> I will try tomorrow the HibernateSessionManager.commit. But what do you
>>> think, guys, about Hibernate Interceptor? It has something similar to
>>> what Kalle mentioned, afterTransactionCompletion
>>> and beforeTransactionCompletion. Have you ever used it with Tapestry?
>>>
>>
>> The company I work uses it with Tapestry for some low-level stuff (mostly
>> setting modified date properties automatically and similar stuff). But I
>> think a JPA hook would be a better choice. The Interceptor hooks happen for
>> *all* the transactions in your SessionFactory, and JPA hooks are more
>> fine-grained.
>>
>>
>> --
>> Thiago H. de Paula Figueiredo
>> Tapestry, Java and Hibernate consultant and developer
>> http://machina.com.br
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>

Re: Calling method after CommitAfter call

Posted by g kuczera <gk...@gmail.com>.
>
> But I think a JPA hook would be a better choice. The Interceptor hooks
> happen for *all* the transactions in your SessionFactory, and JPA hooks are
> more fine-grained.

I am not really into JPA thing, but if I understand well I have to add the
whole new configuration (in AppModule), as stated here:
https://tapestry.apache.org/integrating-with-jpa.html

All my classes are Daos and Dtos which uses the org,hibernate.Session (at
least the Daos).

2016-02-24 23:55 GMT+01:00 Thiago H de Paula Figueiredo <th...@gmail.com>
:

> On Wed, 24 Feb 2016 19:33:13 -0300, g kuczera <gk...@gmail.com> wrote:
>
> I will try tomorrow the HibernateSessionManager.commit. But what do you
>> think, guys, about Hibernate Interceptor? It has something similar to
>> what Kalle mentioned, afterTransactionCompletion
>> and beforeTransactionCompletion. Have you ever used it with Tapestry?
>>
>
> The company I work uses it with Tapestry for some low-level stuff (mostly
> setting modified date properties automatically and similar stuff). But I
> think a JPA hook would be a better choice. The Interceptor hooks happen for
> *all* the transactions in your SessionFactory, and JPA hooks are more
> fine-grained.
>
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: Calling method after CommitAfter call

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Wed, 24 Feb 2016 19:33:13 -0300, g kuczera <gk...@gmail.com> wrote:

> I will try tomorrow the HibernateSessionManager.commit. But what do you
> think, guys, about Hibernate Interceptor? It has something similar to  
> what Kalle mentioned, afterTransactionCompletion
> and beforeTransactionCompletion. Have you ever used it with Tapestry?

The company I work uses it with Tapestry for some low-level stuff (mostly  
setting modified date properties automatically and similar stuff). But I  
think a JPA hook would be a better choice. The Interceptor hooks happen  
for *all* the transactions in your SessionFactory, and JPA hooks are more  
fine-grained.

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Calling method after CommitAfter call

Posted by g kuczera <gk...@gmail.com>.
>
> I'm sorry, I disagree. It's called Commit*After*, so I read that as the
> commit is done *after* the method call. It's not CommitWithin. :)


By using "module" I meant my piece of code:) Somebody - it was not me! -
have called the function before being sure, that the transaction is
committed. Or (s)he did not now, that CommitAfter commits after the hole
function being executed.

I will try tomorrow the HibernateSessionManager.commit. But what do you
think, guys, about Hibernate Interceptor? It has something similar to what
Kalle mentioned, afterTransactionCompletion
and beforeTransactionCompletion. Have you ever used it with Tapestry? I
think that I would have to have the queue with pending email-events and
serve/send them properly in afterTransactionCompletion. What do you think?

2016-02-24 22:35 GMT+01:00 Thiago H de Paula Figueiredo <th...@gmail.com>
:

> On Wed, 24 Feb 2016 17:23:36 -0300, g kuczera <gk...@gmail.com> wrote:
>
> Hi guys,
>>
>
> Hi!
>
> It looks that the above module is badly designed. It does not matter that
>> there is the CommitAfter annotation, if I call the methods which assume
>> that everything is commited from within the commiting method.
>>
>> Am I right?
>>
>
> I'm sorry, I disagree. It's called Commit*After*, so I read that as the
> commit is done *after* the method call. It's not CommitWithin. :)
>
> Also, I completely agree with what Kalle said. If the annotation, which is
> a convenience for simple scenarios, doesn't fit your scenario, don't use
> it. Instead, you can use the HibernateSessionManager.commit() directly.
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: Calling method after CommitAfter call

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Wed, 24 Feb 2016 17:23:36 -0300, g kuczera <gk...@gmail.com> wrote:

> Hi guys,

Hi!

> It looks that the above module is badly designed. It does not matter that
> there is the CommitAfter annotation, if I call the methods which assume
> that everything is commited from within the commiting method.
>
> Am I right?

I'm sorry, I disagree. It's called Commit*After*, so I read that as the  
commit is done *after* the method call. It's not CommitWithin. :)

Also, I completely agree with what Kalle said. If the annotation, which is  
a convenience for simple scenarios, doesn't fit your scenario, don't use  
it. Instead, you can use the HibernateSessionManager.commit() directly.

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org