I'll give that a try, thanks.

Paul Benedict wrote:
Adam,

I have never seen anyone attach Spring transactional logic to an action, and called DAOs straight from the action. That's not good practice, because it mashes web, business, and data layers all in one place.

I wouldn't blame struts here (yet). I'd first move your code into a service object and then inject the service into the action. If there really is a problem with Struts, then the problem will persist (pun intended); but when you move them to the service layer, it will indicate whether you have mis-configured Spring or if Struts is at fault.

Paul

Adam Ruggles wrote:
I am following the guide here http://cwiki.apache.org/S2WIKI/struts-2-spring-2-jpa-ajax.html

For some reason when trying to map a method other than execute I recieve the following error:
- Servlet.service() for servlet default threw exception
java.lang.NoSuchMethodException: $Proxy18.find()

Below are the configuration files and a segment of the UserAction class.

struts.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
  "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
  "http://struts.apache.org/dtds/struts-2.0.dtd";>
<struts>
  <constant name="struts.objectFactory" value="spring" />
  <!-- <constant name="struts.devMode" value="true" />  -->
  <include file="struts-default.xml"/>
    <package name="havoc" extends="struts-default">
      <action name="list" class="userAction" method="execute">
          <result name="success">/WEB-INF/pages/list.jsp</result>
      </action>
      <action name="save" class="userAction" method="save">
          <result name="success" type="redirect">/list.action</result>
      </action>
      <action name="find" class="userAction" method="find">
          <result name="success">/WEB-INF/pages/index.jsp</result>
      </action>
  </package>
</struts>

Application Context
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" xmlns="http://www.springframework.org/schema/beans";
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
      xmlns:aop="http://www.springframework.org/schema/aop";
      xmlns:tx="http://www.springframework.org/schema/tx";
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd";>

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" autowire="no">
      <property name="location" value="/WEB-INF/havoc.properties"/>
  </bean>

  <bean id="config" class="com.havoc.forum.util.Config" autowire="no">
      <property name="location" value="/WEB-INF/havoc.properties"/>
  </bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${jdbc.driverClassName}"/>
      <property name="url" value="${jdbc.url}"/>
      <property name="username" value="${jdbc.username}"/>
      <property name="password" value="${jdbc.password}"/>
  </bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
      <property name="dataSource" ref="dataSource"/>
<!-- This will cause spring to return the raw SessionFactory instead of the spring proxied one. --> <!-- <property name="exposeTransactionAwareSessionFactory" value="false" /> --> <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/> <property name="configLocation" value="classpath:hibernate.cfg.xml"/> <property name="hibernateProperties">
          <props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.bytecode.use_reflection_optimizer">${hibernate.bytecode.use_reflection_optimizer}</prop> <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop> <prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop> <prop key="hibernate.current_session_context_class">thread</prop> <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
          </props>
      </property>         </bean>
  <!--
Instruct Spring to perform declarative transaction management automatically
      on annotated classes.
  -->
  <tx:annotation-driven transaction-manager="transactionManager" />
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"><ref bean="sessionFactory"/></property>
  </bean>

  <!-- Model Objects -->
  <bean id="user" class="com.havoc.forum.model.User" />
  <bean id="group" class="com.havoc.forum.model.Group" />
  <bean id="rank" class="com.havoc.forum.model.Rank" />

  <!-- Data Access Objects -->
  <bean id="userDAO" class="com.havoc.forum.dao.hibernate.UserDAO" />
  <bean id="groupDAO" class="com.havoc.forum.dao.hibernate.GroupDAO" />
  <bean id="rankDAO" class="com.havoc.forum.dao.hibernate.RankDAO" />
    <!-- Actions -->
<bean id="userAction" class="com.havoc.forum.action.UserAction" scope="prototype" />
 </beans>

UserAction

public class UserAction extends ActionSupport {

  ...
  ...

  /**
   * Returns a user from the database or a new user.
   * @return SUCCESS or ERROR.
   * @throws Exception if an error occurs.
   */
@Transactional(readOnly = true, propagation = Propagation.REQUIRED, rollbackFor = PersistenceException.class)
  public String find() {
      if (user != null && user.getId() != null) {
          user = userDAO.find(user.getId());
          return SUCCESS;
      }
      user = new User();
      return SUCCESS;
  }



---------------------------------------------------------------------
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