Or, use Tapernate!  Other folks are using it and they seem to like it a lot.
It does roughly the same thing as the Spring OpenSessionInViewFilter, but it
also does a whole lot more.  Check out the documentation at:

www.carmanconsulting.com/tapernate

James

-----Original Message-----
From: albartell [mailto:[EMAIL PROTECTED] 
Sent: Thursday, June 08, 2006 12:37 PM
To: 'Tapestry users'
Subject: Tapestry+Spring+Hibernate was ->RE: @For within a @contrib:Table

Ok, I have looked into the Tapestry+Spring+Hibernate approach prescribed by
Eric and have some questions.  I am going to go into some code depth for the
archives. Note that I have visited
http://wiki.apache.org/tapestry/FrequentlyAskedQuestions/SpringHibernate and
some other threads in this list but think that I still need some final
clarification from someone who has lived it and can state that my following
scenario will be addressed by the introduction of Spring into the mix.

Currently I use myeclipseide.com to generate my DAO POJO's from MySQL
tables. In the relationship of a Lead (parent) to Leadtag (child) it creates
the following class (note the absence of any Hibernate related code)... 

public abstract class AbstractLead  implements java.io.Serializable {
    private Set leadtags = new HashSet(0);
...code ommitted for brevity sake...
    public Set getLeadtags() {
        return this.leadtags;
    }
    public void setLeadtags(Set leadtags) {
        this.leadtags = leadtags;
    }
} 


The above is "fronted" by the Lead.hbm.xml file which is as follows:
<hibernate-mapping>
    <class name="com.rxs.dao.Lead" table="lead" catalog="rxsweb">
        <id name="leaduid" type="java.lang.Integer">
            <column name="leaduid" />
            <generator class="native" />
        </id>
 ...code ommitted for brevity sake...
        <set name="leadtags" inverse="true">
            <key>
                <column name="leaduid" not-null="true" />
            </key>
            <one-to-many class="com.rxs.dao.Leadtag" />
        </set>
    </class>
</hibernate-mapping>


My hibernate.cfg.xml file is configured as follows:
<hibernate-configuration>
        <session-factory>
                <property
name="connection.datasource">java:comp/env/jdbc/rxscp</property>
                <property
name="dialect">org.hibernate.dialect.MySQLDialect</property>
                <property name="hibernate.show_sql">true</property>

                <mapping resource="com/rxs/dao/Lead.hbm.xml" />
                <mapping resource="com/rxs/dao/Leadtag.hbm.xml"></mapping>
        </session-factory>
</hibernate-configuration>

I configure the DBCP (specified above) in the /META-INF/context.xml file as
follows:
<Context path="/rxs" docBase="/rxs"
 debug="0" reloadable="false">
        <Resource 
                name="jdbc/rxscp" 
                auth="Container" 
                type="javax.sql.DataSource"
                factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"

                maxActive="100" 
                maxIdle="30"
                minIdle="10" 
                maxWait="15000"
                username="myuser" 
                password="mypassword" 
                driverClassName="com.mysql.jdbc.Driver"         
                url="jdbc:mysql://localhost:3306/mydb" 
                removeAbandoned="true" 
                removeAbandonedTimeout="300" 
                validationQuery="select 1"
                logAbandoned="true" 
                testOnBorrow="true"
                testOnReturn="true"
                testWhileIdle="true"
                 />
</Context> 

Here is where my problem comes. I traditionally have used a Servlet filter
to initiate a single session per request as per the below DBConn.java code.
When I need to make a call to the database I simply do a
DBConn.sess().createQuery(...etc.  The DBConn.sess() approach works great
for when I want to manually do a specific query that isn't facilitated by
the getters built by myeclipseide.com; but when I want to make use of
getLeadtags() to produce a list it is not using DBConn.sess() but is instead
invoking a new DB connection somehow someway (I have no idea how it does it,
I just like the work I DON'T have to do:-)

So I guess my question is this: Given the two methods of DB access I am
doing (i.e. manual way using DBConn.sess(), and Hibernates zero code
approach) will OpenSessionInViewFilter be able to appropriately intercept
both and my lazy loading woes will be resolved?


public class DBConn implements Filter {
    private static Logger logger = Logger.getLogger(DBConn.class.getName())
    private static SessionFactory sessionFactory;
    private static ThreadLocal tl = new ThreadLocal();

    static {
        try {
            sessionFactory = new
Configuration().configure().buildSessionFactory();
        } catch (HibernateException e) {
            System.err.println("Initial SessionFactory creation failed." +
e);
            e.printStackTrace();
            throw new ExceptionInInitializerError(e);
        }
    }
    public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
            throws IOException, ServletException {
        try {
            chain.doFilter(request, response);
        } finally {
            Session s = (Session) tl.get();
            if (s != null) {
                try {
                    s.flush();
                    s.close();
                } catch (HibernateException e) {
                    e.printStackTrace();
                }
                tl.set(null);
            }
        }
    }
    public static Session sess() {
        Session s = (Session) tl.get();
        if (s == null || !s.isOpen()) {
            try {
                s = sessionFactory.openSession();
            } catch (HibernateException e) {
                e.printStackTrace();
            }
            tl.set(s);
        }
        return s;
    }
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void destroy() {
    }
}

Aaron Bartell
http://mowyourlawn.com/blog

-----Original Message-----
From: Eric Fesler [mailto:[EMAIL PROTECTED] 
Sent: Thursday, June 08, 2006 8:26 AM
To: Tapestry users
Subject: Re: @For within a @contrib:Table

Hi,

I already had this issue in the past. It was due to the fact that the
leadtagtype (or equivalent) method was called on the leadtag bean after the
hibernate session was closed.

There are two ways to solve the issue.
1°) Do not use lazy loading for the leadtagtype association
2°) Use the OpenSessionInViewFilter of the Spring framework. This filter
opens the session only once per request and close it at the end of the
request.

--ERic


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to