-->
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.  [ 8 posts ] 
Author Message
 Post subject: EJBInterceptor & ServletFilter interfere with each other
PostPosted: Thu Aug 26, 2004 9:02 am 
Beginner
Beginner

Joined: Mon Aug 16, 2004 6:09 am
Posts: 46
Location: Geneva, Switzerland
Steve,

I'm just wondering if you already get the solution for this issue, so I just need to wait for the new release?

I described it earlier here http://forum.hibernate.org/viewtopic.php?t=933527 and your welcomed for suggestions.

octopus wrote:
Besides this, there's one more problem here. It's all fine when only EjbInterceptor is configured in container-configuration (providing session.flush() is added).
But when I configure also servlet filter (exactly following Wiki instructions) it all get wrong. For example, when I deploy my ear with ejb & web modules:

1. Container deploys EJB module.
2004-08-16 13:48:59,543 DEBUG [org.jboss.hibernate.session.EjbInterceptor] Configuring EjbInterceptor [service=jboss.har:service=Hibernate, scope=transaction]

SessionContext.prepareSessionFactory("java:/hibernate/SessionFactory", Scope.TRANSACTION) called here.

2. Container installs servlet filter.
2004-08-16 14:02:42,418 DEBUG [org.jboss.hibernate.session.FilterInterceptor] Configuring FilterInterceptor [service=jboss.har:service=Hibernate, scope=thread]

SessionContext.prepareSessionFactory("java:/hibernate/SessionFactory", Scope.THREAD) called here which overrides scope for this jndiName in scopes Hashtable.

3. I call an ejb from my scheduled service (NOT from a servlet). In ejb I get a session: SessionContext.getSession("java:/hibernate/SessionFactory") and I given a session with scope THREAD and which is not enlisted in transaction! this is not correct behaviour for ejb.



steve wrote:
Well of course! How can this be any different? Any suggestions (or fixes) most welcome...


octopus wrote:
Steve,

If I install both EjbInterceptor & Servlet filter there're two contexts and they should not interfere with each other. (I suppose interceptor configured with transaction scope and filter with thread scope).

In current implementation SessionContext.getSession needs to be passed both jndiName and scope to return correct context because it cannot guess from where it is called.
Session session = SessionContext.getSession("java:/hibernate/SessionFactory", Scope.TRANSACTION);
But when I explicity configured filter/interceptor for particular scope - why should I say it again?

I would suggest to bind correct session to JNDI in Interceptor/Filter. then just lookup session in bean/servlet

Session session = (Session) new InitialContext().lookup("java:comp/HibernateSession");

I've just sketchy implemented it and it seems to work fine. Just wondering if you like the approach?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 30, 2004 4:24 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
No, the jndi name of the session-factory in this context is really just a convenience namespace for handles to sessions. The scope is just an implementation detail of the interceptors, describing how you want the resultant session managed internally (really it only describes cleanup semantics). It is totally intended that sessions from a given session factory be bound with only a single scope for a given call stack. Actually, what should happen is you should get an exception if you try to register two session management interceptors for the same session factory with differeing scopes.

But really, what is a valid use case for having a session bound twice with both thread and transaction scope? Or even two sessions from the same session factory with different scopes? I can't think of any; if you can give me *valid* use cases where this is desirable, then I'll rethink this.

Don't forget that the web filter interceptor can be used with scope="transaction"; you'll just have to apply a filter earlier in the chain which begins a transaction.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 31, 2004 1:49 pm 
Beginner
Beginner

Joined: Mon Aug 16, 2004 6:09 am
Posts: 46
Location: Geneva, Switzerland
Steve,


My use case is very simple, I think this is the most common case when I need hibernate/jboss integraiton.

1. I have one hibernate service.
2. I use it from both servlet & ejb.
3. From either context, I want just call getSession() when I need hibernate session, work with it and forget about any cleanup code.
4. I want than hibernate session what I used in servlet was flushed and closed when I return from servlet,
respectively, I want the session I get being in ejb was flushed and closed when CMT commits.

If this usecase fits well into existing architecture, maybe you can explain it here or in wiki?



My experience is based on existing wiki page, and what I get:

Lets suppose I have my hibernate service deployed, say, as jboss.har:service=MyHibernateService.

Hibernate session is described as unit of work which is in my understanding (usually)
transaction-wide for ejb and servlet's service()-wide for servlet.

I have ejb's and servlets which want to use it. Basically, I need to get hibernate session
in servlet or ejb. In both cases I just get session like this:
Session session = SessionContext.getSession("java:/hibernate/MySessionFactory");

providing service deployed with
<mbean code="org.jboss.hibernate.jmx.Hibernate" name="jboss.har:service=MyHibernateService">
<attribute name="SessionFactoryName">java:/hibernate/MySessionFactory</attribute>

In servlet I want session was opened before entering servlet (or maybe lazy when I call getSession())
and flushed and closed when I left servlet.

In ejb I want session to be flushed and closed when transaction commited.

so the idea is just getSession() when I need it and forget about explicit flushing and closing.

How should I configure filter & interceptor?

according to wiki:

<container-name>Hibernate Stateless SessionBean</container-name>
<interceptor service="jboss.har:service=MyHibernateService" scope="transaction">org.jboss.hibernate.session.EjbInterceptor</interceptor>

and

<filter-name>Hibernate Session Filter</filter-name>
<filter-class>org.jboss.hibernate.session.FilterInterceptor</filter-class>
<init-param>
<param-name>service</param-name>
<param-value>jboss.har:service=MyHibernateService</param-value>
</init-param>
<init-param>
<param-name>scope</param-name>
<param-value>thread</param-value>
</init-param>

respectively.

I need access to concrete hibernate service (jboss.har:service=MyHibernateService) identified by
its SessionFactoryName (java:/hibernate/MySessionFactory)

After adding filter & interceptor to my application config I code in ejb something like this:

session = getSession("java:/hibernate/MySessionFactory");
entity = session.load(...);
session.save(entity)

and I expect session will be flushed and closed when my CMT commited.

But I get session with scope THREAD as it was described in servlet filter - because it's the same
factory name and it was overriden.

Well, I need both servlet & ejb get session from this factory (java:/hibernate/MySessionFactory), but session management should be different in terms of cleanup (you're saying this as well).

steve wrote:
No, the jndi name of the session-factory in this context is really just a convenience namespace for handles to sessions. The scope is just an implementation detail of the interceptors, describing how you want the resultant session managed internally (really it only describes cleanup semantics).


Right, it's all about cleanup.

steve wrote:
It is totally intended that sessions from a given session factory be bound with only a single scope for a given call stack.


Please correct me if I'm wrong. But it seems that I have exactly one session factory bound to one hibernate service. (session factory name defined in hibernate service xml). I get sessions from
this factory from different contexts (basically servlets&ejbs) where I expext different cleanup
behaviour, according to scope defined in interceptors. But you allow define only one scope(=cleanup strategy) per session factory(=hibernate service).

steve wrote:
But really, what is a valid use case for having a session bound twice with both thread and transaction scope? Or even two sessions from the same session factory with different scopes? I can't think of any; if you can give me *valid* use cases where this is desirable, then I'll rethink this.


I do not understand this. Session factory produces sessions.
Session factory itself doesn't care of how session will be closed.
Closing algorithm defined by context.
Then, why can't I have two sessions from one factory which being used in different contexts have different cleaning strategy??


Thanks,


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 31, 2004 11:05 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Quote:
4. I want than hibernate session what I used in servlet was flushed and closed when I return from servlet,
respectively, I want the session I get being in ejb was flushed and closed when CMT commits.

But in your scenario and description, these would need to be seperate Sessions. I say this because if you mean the same session, then stuff done in the ejb would be under JTA, but stuff done in the servlet would not be under JTA; this is baaaaad! You are correct, a Session is essentially a unit-of-work; having part of that UOW under JTA control but not other parts is not good.

So which do you mean?

Quote:
unit of work which is in my understanding (usually)
transaction-wide for ejb and servlet's service()-wide for servlet.

Not necessarily. What about web applications that process requests in a staged manner (e.g., via multiple servlet forwards)? Obviously they cannot fit into your descrption. And anyway, the point is that the term unit-of-work is synonymous with application-transaction. These do not necessarily correalate to JTA transactions, but in enterprise applications dealing with databases the scope of a unit-of-work is most usually demarcated via JTA transactions.

You have to understand that within JBoss in particular processing in a servlet that calls into an ejb actually occurs within the same context. So what I am asking you is for valid use cases where the current Session for a given context should be different depending on whether I happen to be in a servlet or in an ejb, given that they occur within the same context.

Think of this in terms of how JTA transactions work in app servers. These interceptors are akin to "REQUIRED" semantics for CMT transactions. Its not like you can have a servlet start a transaction and then call into an ejb which participates in "REQUIRED" CMT and have that ejb call performed in a seperate transaction. But this is really what you are saying you want for these managed sessions.

Quote:
How should I configure filter & interceptor? according to wiki: ...

These are examples, and thus not the only valid ways to configure these. As the wiki states further down, if you want to use the filter interceptor with scope="transaction" (which is what you would want here) that you need to apply a seperate filter previously in the filter chain which opens/closes a JTA transaction.[/b]


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 02, 2004 7:58 am 
Beginner
Beginner

Joined: Mon Aug 16, 2004 6:09 am
Posts: 46
Location: Geneva, Switzerland
octopus wrote:
4. I want than hibernate session what I used in servlet was flushed and closed when I return from

servlet,
respectively, I want the session I get being in ejb was flushed and closed when CMT commits.

steve wrote:
But in your scenario and description, these would need to be seperate Sessions. I say this because if

you mean the same session, then stuff done in the ejb would be under JTA, but stuff done in the servlet

would not be under JTA; this is baaaaad! You are correct, a Session is essentially a unit-of-work;

having part of that UOW under JTA control but not other parts is not good.

So which do you mean?

You're absolutely right! Of course I do not want a single session through servlet-ejb call.
Even more, for simplification, I'm considering use case where are no calls from servlet to ejb.

1. I have a servlet which just wants to load hibernate entity and, say, print it's content.
2. I have an ejb which is called from outside, say, from MDB. no servlets involved.
3. They both use same hibernate service, NOT the same session, of course.

For servlet, I define filter, with scope THREAD, right? There's no JTA involved, and I do not really

need it.
For ejb, I do have required transaction attribute, ejb-ejb calls, and I really need hibernate session
enlisted in transaction. Here I need to apply ejb interceptor with scope TRANSACTIOn, right?

This servlet & ejb have no relations, even more - they are in separate modules (I have set of ejb/war/

ear modules which all should use the same hibernate module which provides persistance service for all of

them).
The problem is even being deployed separately (webapp & ejbapp which do not know of each other)
at the moment of deployment filter&interseptor ought to register itself against the SAME factory (java

:/hibernate/MySessionFactory)

steve wrote:
Not necessarily. What about web applications that process requests in a staged manner (e.g., via

multiple servlet forwards)? Obviously they cannot fit into your descrption. And anyway, the point is

that the term unit-of-work is synonymous with application-transaction. These do not necessarily

correalate to JTA transactions, but in enterprise applications dealing with databases the scope of a

unit-of-work is most usually demarcated via JTA transactions.

Right, right again. No problems with forwards as it implemented now: session is closed by filter which opened it. servlets you're forwarded to use the same session as it is already bound in this thread.

steve wrote:
You have to understand that within JBoss in particular processing in a servlet that calls into an ejb

actually occurs within the same context. So what I am asking you is for valid use cases where the

current Session for a given context should be different depending on whether I happen to be in a servlet

or in an ejb, given that they occur within the same context.

No, no Steve! Never talked about servlet calling ejb like this. They are actually in different applications and never know about each other.

1. I deploy app1. only ejbs. interceptor configured to TRAN. I calling ejb via, say, RMI. EJB gets hib session which enlisted in JTA and all works perfect.

2. I deploy app2. only servlets. filter configured to THREAD. I'm calling servlet.. everything correct.

3. I'm calling ejb from app1. It gets session as usually
SessionContext.getSession("java:/hibernate/MySessionFactory");

NOTE: this session won't be enlisted in JTA because SessionContext statically keep SCOPE associated
with session factory name. Session FACTORY name is the same everywhere, but SESSIONS I get form this
factory should be cleaned differently, according to filter/interceptor configuration.


steve wrote:
Think of this in terms of how JTA transactions work in app servers. These interceptors are akin to "

REQUIRED" semantics for CMT transactions. Its not like you can have a servlet start a transaction and

then call into an ejb which participates in "REQUIRED" CMT and have that ejb call performed in a

seperate transaction. But this is really what you are saying you want for these managed sessions.

No, no. Again: I'm considering much simpler use case where is no servlet-ejb call.
See: I have plenty of applications which all use the same hibernate service as persistance layer.
I just want to allow configure different cleanup polices appliend to different sessions taken from the same session factory (which is my hibernate service).

this code:
Code:
private static Hashtable scopes = new Hashtable();
scopes.put(jndiName, scope);

creates 1:1 association between hibernate service name and particular scope, right?
therefore, there's no way to use this service from contexts where different stategies should be applied.
Even it these contexts absolutely separated from each other (even resided in different apps).

Thanks,

PS.
Guys, if anyone also interested in this stuff please share you opinion.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 02, 2004 8:40 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Ah.. ok, you mean multiple independent usages of the same session factory. Let me think about this for a little.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 02, 2004 10:47 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Ok, I definitely do not like binding the sessions to jndi. I am adding an additional optional parameter to the config for the various interceptors that allow you to define a "sessionName". If not defined, this defaults to the jndi name for the session factory.

In your case, the servlet filter and ejb inerceptor would just need to define seperate "sessionName"s. This is used as the key for lookup in the SessionContext.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 03, 2004 6:32 am 
Beginner
Beginner

Joined: Mon Aug 16, 2004 6:09 am
Posts: 46
Location: Geneva, Switzerland
Steve,

Thanks for understanding. This is solution for the problem, although not perfect. Let me explain.

The idea of container-managed-something is that we delegate management tasks to container,
according to management rules configured at container level. Managed code just accesses resource
by name, expecting resource will be provided according to context it was requested from, right?
Container cares or all resource managed and lifecycle issues.

Back to the given example. You suggest I configured name in filter/interceptor and access session
by this name, not resource name. It creates unnecessary dependancy of managed code on container configuration.

steve wrote:
In your case, the servlet filter and ejb inerceptor would just need to define seperate "sessionName"s. This is used as the key for lookup in the SessionContext.


Suppose I have hibernate service MyHibernateService1.
I'm configuring filter/interceptor to work with this service sessions. Any idea of the naming policy? ;)

MyHibernateService1Servlet & MyHibernateService1EJB?
or MyHibernateService1ThreadScope & MyHibernateService1TransactionScope?
just random names?

Does it matter? Yes. If I have some utility code, for example:

System.out.writeln("Now my entity is: "+session.load(Entity.class, key));

It doesn't belong to any particular servlets/ejbs.
How should I access session if this code can be called from different contexts?

I always know MyHibernateService1 name (aka jndiName aka ObjectName), therefore I always can
get session with code like getSession("MyHibernateServiceName");

But to code proper name defined in filter/interceptor I do need to know context
it will be called from to put a proper name in getSession parameter.

This is not exactly what I'm expecting from container service management.

Does it seems reasonable for you? I do want to access session by factory name(=service name).

I implemented this behavour via jndi binding. You don't like it? Ok, I'll suggest how to keep
your interface SessionContext.getSession("java:/hibernate/SessionFactory") but without explicit
references to context configuration and scoping inside the managed code. Let me think about it.

Do you think it makes sense?


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