Hi all,

After about 5 minutes of "omfg not that error again", I think I found a
quick hack to avoid org.hibernate.LazyInitializationException with
WicketTester. I've checked everywhere on the lists but didn't find a similar
solution, so apologies if someone else already posted this. There may also
be a better way to do it.

If I can explain it properly:

* I have an abstract BaseAdminApplication class that extends WebApplication,
and does the standard application configurations (mounting/stuff), but no
Spring injection configuration yet.

* Then I have a SpringAdminApplication that extends from
BaseAdminApplication. This is referenced for the normal
applicationContext.xml, and correctly configures Spring Injection.

* There is another subclass, called JUnitAdminApplication, that also extends
from BaseAdminApplication. This is referenced in the Unit Testing
application context.

* The JUnitAdminApplication mimics the OSIV pattern, inside Wicket's
WebSession.attach() and .detach() methods.

* Configure Spring Injection outside of the WebApplication. For some reason
there were odd errors when configuring during the WebApplication.init()
process.

I do hope it makes sense. Unfortunately I can't give out all the code, but
I'm sure it'll set the next person on the right track before redoing tests
with Selenium at the 11th hour. So far there are no strange surprises, yet.

---------------------------

package com.SECRETAPP.web;

import ..............;

public class JUnitAdminApplication extends BaseAdminApplication {
    @Autowired
    SessionFactory sessionFactory;

    @Override
    public Session newSession(Request request, Response response) {
        return new WebSession(request) {
            @Override
            protected void attach() {
                // Do the attach magic that I don't care about right now
                super.attach();

                // Force the creation of a new Hibernate session using
Spring
                SessionFactoryUtils.getSession(sessionFactory, true);

                // Force the session to be closed only when we tell it to
                // By default, the Hibernate session is closed somewhere
during
                // the request cycle. Similar to OpenSessionInViewFilter
                SessionFactoryUtils.initDeferredClose(sessionFactory);
            }


            @Override
            protected void detach() {
                super.detach();
                // Only close the Hibernate Session now, after all rendering
is done
                SessionFactoryUtils.processDeferredClose(sessionFactory);
            }

        };
    }

    // Other code...
}

----------------

In com/SECRETAPP/web/BaseTester-context.xml ......

<beans.....>
    <context:component-scan base-package="com.SECRETAPP" />

    <bean id="wicketApplication"
class="com.SECRETAPP.web.JUnitAdminApplication"/>


    <!-- other stuff -->
</beans>

--------------------

In my WicketTestBase abstract class...

public abstract class WicketTestBase {

    // Stripped code

    protected WicketTester createTester() {
        if(tester != null) {
            return tester;
        }
        WebApplication app = (WebApplication)
applicationContext.getBean("wicketApplication");

        tester = new WicketTester(app) {

            @Override
            public ServletContext newServletContext(String path) {
                MockServletContext servletContext = (MockServletContext)
super.newServletContext(path);


servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
applicationContext);
                return servletContext;
            }
        };

        app.addComponentInstantiationListener(new
SpringComponentInjector(tester.getApplication(), applicationContext, true))

        // Stripped code

        return tester;
    }
}

Reply via email to