Putting Cayenne Files in Web Application CLASSPATH

When deploying an application in a web container it is possible to follow the procedure for the standalone applications, i.e. put all XML files in the application CLASSPATH (e.g. in "mywebapp/WEB-INF/classes/", but DON'T put it in container shared locations!). Session DataContext can be obtained via ServletUtil:

HttpSession session = ...;
DataContext context = ServletUtil.getSessionContext(session);

However you may consider a deployment procedure described below, as it provides more flexibility and a number of additional useful features.

Cayenne Servlet Filter

Adding the following filter to the web.xml would automate Cayenne setup in the web application:

<filter>
    <filter-name>CayenneFilter</filter-name>
    <filter-class>org.apache.cayenne.conf.WebApplicationContextFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CayenneFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

The filter will ensure that for each matching request a DataContext is bound to the request thread. So you can retrieve it anywhere in the application, even if you don't have a reference to the web environment:

DataContext context = DataContext.getThreadDataContext();

Filter can match a specific URL as shown above, or a specific servlet:

<servlet>
   <servlet-name>MyServlet</servlet-name>
   <servlet-class>org.example.MyServlet</servlet-class>
   <load-on-startup>0</load-on-startup>
</servlet>
		
<filter>
    <filter-name>CayenneFilter</filter-name>
    <filter-class>org.apache.cayenne.conf.WebApplicationContextFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CayenneFilter</filter-name>
    <servlet-name>MyServlet</servlet-name>
</filter-mapping>

Additionally the filter supports putting files in myapp/WEB-INF/ directory instead of the CLASSPATH, so a .war file may look like this:

index.jsp
WEB-INF/cayenne.xml
WEB-INF/xyz.map.xml
WEB-INF/lib/...

Actually, Cayenne files can be stored in any subdirectory of myapp/WEB-INF/. To specify a subdirectory, you'll need to add <context-param> named cayenne.configuration.path to your application descriptor:

<context-param>
    <param-name>cayenne.configuration.path</param-name>
    <param-value>/WEB-INF/config/cayenne-files</param-value>
</context-param>