Monday, 31 May 2010

GWT 2 Spring 3 JPA 2 Hibernate 3.5 Tutorial


This step by step guide will present how to develop a simple web application using Google's Web Toolkit (GWT) for the rich client and Spring as the back – end, server side framework. The sample web application will provide functionality to make CRUD (Create Retrieve Update Delete) operations to a database. For the data access layer we will use JPA over Hibernate and for a database we will use Hypersonic. Of course you can change the configuration and use whatever you like. We will deploy the web application to an Apache – Tomcat instance.

Our preferred development environment is Eclipse, so as a prerequisite you must have Eclipse with GWT support installed. The installation of the GWT plugin for Eclipse is out of the scope of this tutorial and will not be discussed. Nevertheless you will need the following components :
  1. Eclipse from here
  2. GWT Plugin for Eclipse from here
  3. Spring framework distribution from here
  4. Hibernate persistence framework distribution from here
  5. Hypersonic database from here
  6. Apache commons-logging library from here
  7. AOP Alliance (Java/J2EE AOP Standard) library from here
  8. SLF4J library from here
  9. Apache log4j library from here
  10. Last but not least, download the GWT – Spring “glue” library spring4gwt from here
We will be using Eclipse Galileo, GWT version 2.0.3, Spring version 3.0.1, Hibernate version 3.5.2, Hypersonic version 1.8.1.2, Apache commons-logging version 1.1.1, AOP Alliance (Java/J2EE AOP Standard) version 1.0, SLF4J version 1.5.8, Apache log4j version 1.2.16 and spring4gwt version 0.0.1 for this tutorial.

Enough talk, lets get our hands dirty!
  1. Create a new GWT project, go to File → New Web Application Project
  2. We will name our project GWTSpring. The base package will be com.javacodegeeks.gwtspring also use only Google Web Toolkit thus uncheck “Use Google App Engine” at the wizard window.
Let's recap a few things about the GWT project structure
  1. /src folder contains all source files of the application
    • {package_name}.client subpackage contains all source files only available to the client side of the application
    • {package_name}.server subpackage contains all source files only available to the server side part of the application
    • {package_name}.shared subpackage contains all source files available to both the client and server side of the application
  2. /test folder contains all source files for unit tests
  3. /war folder contains essential files for creating a valid web application
In order to properly integrate Spring with GWT at runtime, we must provide all necessary libraries to the web application. So copy the files listed below under /war/WEB-INF/lib (copy the relevant files if you are using different versions)

From Spring distribution
  • /dist/org.springframework.expression-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.beans-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.oxm-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.jms-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.jdbc-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.core-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.context-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.asm-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.aspects-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.transaction-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.context.support-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.aop-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.orm-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.instrument-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.instrument.tomcat-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.test-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.web-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.web.portlet-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.web.servlet-3.0.1.RELEASE-A.jar
  • /dist/org.springframework.web.struts-3.0.1.RELEASE-A.jar
From the Hibernate distribution
  • hibernate3.jar
  • /lib/required/antlr-2.7.6.jar
  • /lib/required/commons-collections-3.1.jar
  • /lib/required/dom4j-1.6.1.jar
  • /lib/required/javassist-3.9.0.GA.jar
  • /lib/required/jta-1.1.jar
  • /lib/required/slf4j-api-1.5.8.jar
  • /lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar
  • /lib/optional/c3p0/c3p0-0.9.1.jar
From the Hypersonic distribution
  • /lib/hsqldb.jar
From the Apache Commons Logging distribution
  • commons-logging-1.1.1.jar
From the AOP Alliance (Java/J2EE AOP Standard) distribution
  • aopalliance.jar
From the SLF4J distribution
  • slf4j-log4j12-1.5.8.jar
From the Apache log4j distribution
  • log4j-1.2.16.jar
The sping4gwt library
  • spring4gwt-0.0.1.jar
We now have to take care of dependences for our Eclipse project. The following jars should be included in the Java build path of the project :
  • hibernate-jpa-2.0-api-1.0.0.Final.jar
  • org.springframework.beans-3.0.1.RELEASE-A.jar
  • org.springframework.context-3.0.1.RELEASE-A.jar
  • org.springframework.core-3.0.1.RELEASE-A.jar
  • org.springframework.orm-3.0.1.RELEASE-A.jar
  • org.springframework.transaction-3.0.1.RELEASE-A.jar
The next step is to provide hooks for the web application so as to load the Spring context upon startup and to allow for spring4gwt to intercept RPC calls between the client and the server and transform them to Spring service invocations.

Locate the web.xml file under /war/WEB-INF and add the following :

For loading the Spring context upon startup,
<listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
At the servlets section include
<servlet>
 <servlet-name>springGwtRemoteServiceServlet</servlet-name>
 <servlet-class>org.spring4gwt.server.SpringGwtRemoteServiceServlet</servlet-class>
</servlet>
At the servlet-mapping section include, for spring4gwt to intercept RPC calls.
<servlet-mapping>
 <servlet-name>springGwtRemoteServiceServlet</servlet-name>
 <url-pattern>/gwtspring/springGwtServices/*</url-pattern>
</servlet-mapping>
Things to notice here :
  1. The url-pattern child element of the servlet-mapping element for the springGwtRemoteServiceServlet servlet, should be changed to whatever your GWT module name is e.g. {module_name}/springGwtServices/*, the module name is defined in {project_name}.gwt.xml file (here GWTSpring.gwt.xml) located at the root of the base package of the project under /src folder
  2. You can change the name of spring4gwt servlet (springGwtRemoteServiceServlet here) to whatever you like
To continue we have to create the persistence.xml file so as to describe the connection with the database using JPA. The pesistence.xml file must be located inside a META-INF directory which in turn has to be accessible by the web application at runtime (on the classpath). To fulfill the aforementioned requirements we have to create the META-INF folder under the project's /war/WEB-INF/classes folder. To do so we create a new source folder under the name e.g. “resources” and create the META-INF folder inside it. Finally create the persistence.xml file inside the /resources/META-INF folder. An example persistence.xml is presented below
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">

    <persistence-unit name="MyPersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <properties>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
            <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:javacodegeeks"/>
            <property name="hibernate.connection.username" value="sa"/>
            <property name="hibernate.connection.password" value=""/>

            <property name="hibernate.c3p0.min_size" value="5"/>
            <property name="hibernate.c3p0.max_size" value="20"/>
            <property name="hibernate.c3p0.timeout" value="300"/>
            <property name="hibernate.c3p0.max_statements" value="50"/>
            <property name="hibernate.c3p0.idle_test_period" value="3000"/>
        </properties>

    </persistence-unit>

</persistence>
Things to notice here :
  1. If you intent to deploy the web application to a J2EE application server that supports JTA transactions e.g. JBoss or use other databases e.g. Oracle, MySQL etc, please see our “JBoss Spring JPA Hibernate tutorial” here for alternative configurations
Now lets create the applicationContext.xml file that will drive Spring container. Create the file under /war/WEB-INF directory. An example applicationContext.xml is presented below
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
            http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    <context:component-scan base-package="com.javacodegeeks.gwtspring"/>

    <task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>

    <task:executor id="myExecutor" pool-size="5"/>

    <task:scheduler id="myScheduler" pool-size="10"/>

    <tx:annotation-driven/>

    <bean class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" id="entityManagerFactory">
        <property name="persistenceUnitName" value="MyPersistenceUnit"/>
    </bean>

    <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

</beans>
Things to notice here :
  1. Change the base-package attribute of the context:component-scan element to whatever is the base package of your project so as to be scanned for Spring components (services, DAOs etc).
  2. Change the value attribute of entityManagerFactory bean persistentUnitName property to the name of your persistent unit as dictated in the persistence.xml file
  3. If you intent to deploy the web application to a J2EE application server that supports JTA transactions e.g. JBoss please see our “JBoss Sping JPA Hibernate tutorial” here for alternative configurations
In the last part of this tutorial we are going to present the Data Transfer Object (DTO) for transferring data between the client and the server, the Data Access Object (DAO) that is used to access the database and the Spring service to expose functionality to the GWT Web client.

The DTO is an object that can be used by both the client and the server, thus you should create a “dto” subpackage under the “shared” package and place the DTO there. We are going to create an EmployeeDTO containing information for an employee like below
package com.javacodegeeks.gwtspring.shared.dto;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "EMPLOYEE")
public class EmployeeDTO implements java.io.Serializable {
    
    private static final long serialVersionUID = 7440297955003302414L;

    @Id
    @Column(name="employee_id")
    private long employeeId;
    
    @Column(name="employee_name", nullable = false, length=30)
    private String employeeName;
    
    @Column(name="employee_surname", nullable = false, length=30)
    private String employeeSurname;
    
    @Column(name="job", length=50)
    private String job;
        
    public EmployeeDTO() {
    }

    public EmployeeDTO(int employeeId) {
        this.employeeId = employeeId;        
    }

    public EmployeeDTO(long employeeId, String employeeName, String employeeSurname,
            String job) {
        this.employeeId = employeeId;
        this.employeeName = employeeName;
        this.employeeSurname = employeeSurname;
        this.job = job;
    }

    public long getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(long employeeId) {
        this.employeeId = employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public String getEmployeeSurname() {
        return employeeSurname;
    }

    public void setEmployeeSurname(String employeeSurname) {
        this.employeeSurname = employeeSurname;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

}
The DAO object will be used to access the database and perform CRUD (Create Retrieve Update Delete) operations. It is a server side component so it should be placed under the “server” subpackage of our project. Create a “dao” subpackage and place the DAO there. An example DAO is presented below
package com.javacodegeeks.gwtspring.server.dao;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.javacodegeeks.gwtspring.shared.dto.EmployeeDTO;

@Repository("employeeDAO")
public class EmployeeDAO extends JpaDAO<Long, EmployeeDTO> {
    
    @Autowired
    EntityManagerFactory entityManagerFactory;
    
    @PostConstruct
    public void init() {
        super.setEntityManagerFactory(entityManagerFactory);
    }
    
}
As you can see the EmployeeDAO class extends a basic DAO class (JpaDAO). The EmployeeDAO class can contain specific queries concerning the EmployeeDTO object, but all CRUD operations can be handled from the basic DAO class (JpaDAO). Place the JpaDAO class at the same level as the EmployeeDAO class, under the “dao” subpackage. Below we present the JpaDAO class
package com.javacodegeeks.gwtspring.server.dao; 

import java.lang.reflect.ParameterizedType; 
import java.util.List; 

import javax.persistence.EntityManager; 
import javax.persistence.PersistenceException; 
import javax.persistence.Query; 

import org.springframework.orm.jpa.JpaCallback; 
import org.springframework.orm.jpa.support.JpaDaoSupport; 

public abstract class JpaDAO<K, E> extends JpaDaoSupport { 
    protected Class<E> entityClass; 

    @SuppressWarnings("unchecked") 
    public JpaDAO() { 
        ParameterizedType genericSuperclass = (ParameterizedType) getClass() 
                .getGenericSuperclass(); 
        this.entityClass = (Class<E>) genericSuperclass 
                .getActualTypeArguments()[1]; 
    } 

    public void persist(E entity) { 
        getJpaTemplate().persist(entity); 
    } 

    public void remove(E entity) { 
        getJpaTemplate().remove(entity); 
    } 
    
    public E merge(E entity) { 
        return getJpaTemplate().merge(entity); 
    } 
    
    public void refresh(E entity) { 
        getJpaTemplate().refresh(entity); 
    } 

    public E findById(K id) { 
        return getJpaTemplate().find(entityClass, id); 
    } 
    
    public E flush(E entity) { 
        getJpaTemplate().flush(); 
        return entity; 
    } 
    
    @SuppressWarnings("unchecked") 
    public List<E> findAll() { 
        Object res = getJpaTemplate().execute(new JpaCallback() { 

            public Object doInJpa(EntityManager em) throws PersistenceException { 
                Query q = em.createQuery("SELECT h FROM " + 
                        entityClass.getName() + " h"); 
                return q.getResultList(); 
            } 
            
        }); 
        
        return (List<E>) res; 
    } 

    @SuppressWarnings("unchecked") 
    public Integer removeAll() { 
        return (Integer) getJpaTemplate().execute(new JpaCallback() { 

            public Object doInJpa(EntityManager em) throws PersistenceException { 
                Query q = em.createQuery("DELETE FROM " + 
                        entityClass.getName() + " h"); 
                return q.executeUpdate(); 
            } 
            
        }); 
    }
    
}
Finally we are going to create the service interface and implementation classes for the GWT client to access. The service interface should be accessible by both the client and the server, so it should be placed under the “shared” subpackage of our project. Create a “services” subpackage and place the service interface there. An example interface class follows
package com.javacodegeeks.gwtspring.shared.services;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

import com.javacodegeeks.gwtspring.shared.dto.EmployeeDTO;

@RemoteServiceRelativePath("springGwtServices/employeeService")
public interface EmployeeService extends RemoteService {
    
    public EmployeeDTO findEmployee(long employeeId);
    public void saveEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
    public void updateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
    public void saveOrUpdateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
    public void deleteEmployee(long employeeId) throws Exception;
    
}
Things to notice here :
  1. GWT client has to be able to make asynchronous Remote Procedure Calls (RPCs) to the server side service. Thus the service interface must extend the RemoteService interface. An asynchronous counterpart of the specified interface must also be provided to enable asynchronous communication (see below)
  2. We annotate the interface so as to define the URL under which the service will be accessible. As the service is a Spring service we want spring4gwt to intercept the RPC calls and perform a Spring service invocation. To do that we define a relative path that will be handled by “springGwtRemoteServiceServlet” declared in our web.xml as shown above.
  3. The service name declared at “RemoteServiceRelativePath” annotation, here “employeeService”, must match the Spring service bean name. We will define the Spring service bean name in the service implementation class (see below)
The asynchronous counter part of the service interface follows
package com.javacodegeeks.gwtspring.shared.services;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.javacodegeeks.gwtspring.shared.dto.EmployeeDTO;

public interface EmployeeServiceAsync {

    void deleteEmployee(long employeeId, AsyncCallback<Void> callback);

    void findEmployee(long employeeId, AsyncCallback<EmployeeDTO> callback);

    void saveEmployee(long employeeId, String name, String surname,
            String jobDescription, AsyncCallback<Void> callback);

    void saveOrUpdateEmployee(long employeeId, String name, String surname,
            String jobDescription, AsyncCallback<Void> callback);

    void updateEmployee(long employeeId, String name, String surname,
            String jobDescription, AsyncCallback<Void> callback);

}
The service implementation class is a server side component, so we must place it under “server” subpackage of our project. Create the “services” subpackage and place it there. An example service implementation class is presented below
package com.javacodegeeks.gwtspring.server.services; 

import javax.annotation.PostConstruct; 
import javax.annotation.PreDestroy; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 

import com.javacodegeeks.gwtspring.server.dao.EmployeeDAO; 
import com.javacodegeeks.gwtspring.shared.dto.EmployeeDTO; 
import com.javacodegeeks.gwtspring.shared.services.EmployeeService; 

@Service("employeeService") 
public class EmployeeServiceImpl implements EmployeeService { 
    
    @Autowired 
    private EmployeeDAO employeeDAO; 

    @PostConstruct 
    public void init() throws Exception { 
    } 
    
    @PreDestroy 
    public void destroy() { 
    } 

    public EmployeeDTO findEmployee(long employeeId) { 
        
        return employeeDAO.findById(employeeId); 
        
    } 
    
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 
    public void saveEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception { 
            
        EmployeeDTO employeeDTO = employeeDAO.findById(employeeId); 
        
        if(employeeDTO == null) { 
            employeeDTO = new EmployeeDTO(employeeId, name,surname, jobDescription); 
            employeeDAO.persist(employeeDTO); 
        } 
        
    } 
    
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 
    public void updateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception { 
        
        EmployeeDTO employeeDTO = employeeDAO.findById(employeeId); 
        
        if(employeeDTO != null) { 
            employeeDTO.setEmployeeName(name); 
            employeeDTO.setEmployeeSurname(surname); 
            employeeDTO.setJob(jobDescription); 
        } 

    } 
    
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 
    public void deleteEmployee(long employeeId) throws Exception { 
        
        EmployeeDTO employeeDTO = employeeDAO.findById(employeeId); 
        
        if(employeeDTO != null) 
            employeeDAO.remove(employeeDTO); 

    } 
    
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 
    public void saveOrUpdateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception { 
        
        EmployeeDTO employeeDTO = new EmployeeDTO(employeeId, name,surname, jobDescription); 
        
        employeeDAO.merge(employeeDTO); 
        
    } 

} 
Things to notice here :
  1. We use the @Service("employeeService") stereotype annotation so as to declare that this class represents a Spring service by the name "exampleService". The Spring container will instantiate all services at start up.
  2. We use the @Autowire annotation to inject the instance of the DAO class to the "employeeService". For proper instantiation of the service Spring container has to resolve first all potential references among services, so it instantiates the DAO class and injects the instance to the appropriate field of "employeeService" - the "employeeDAO" field. In case you wonder, the dependency injection is done according to type (Class) and if not satisfied according to name, meaning that if we have defined multiple services of the same type (Class) the one injected would be the one with the same name as the designated field.
  3. We use the Java annotations @PostConstruct and @PreDestroy to declare the methods that will be invoked by Spring container after initialization (all dependency injection is done) and prior destruction of the service.
  4. We use the @Transactional annotation for all methods that need to perform update operation on the database (INSERT, UPDATE, DELETE)
  5. We DO NOT use the @Transactional annotation on methods that perform retrieve (FIND) operations on the database (except for objects that contain lazily initialized references - see below), and/or perform no database operations. That is because every time you invoke a method annotated as transactional, Spring container involves in the invocation JPA's entity manager and as a consequence platform's transaction manager, so as to define the transactional behavior that will be applied, introducing a noticeable performance penalty especially for low latency / high throughput applications
  6. For methods that perform retrieve (FIND) operations for objects that contain lazily initialized references you should use the @Transactional annotation, designating "NESTED" propagation type in order for Spring to maintain Hibernate session open for the entire method call
  7. Transactional behavior is applied only on client calls to the service. Transactional behavior is not applied to intra operation calls. For example if a client invokes an operation that is not annotated as transactional and the implementation of the latter introduces a call to another operation of the same service that is annotated transactional then for the combined operations no transactional behavior will be applied
We are almost done!, we have to develop the GWT user interface to access our Spring service. Despite the fact that GWT user interface development is out of the scope of this tutorial we are going to provide a basic user interface just to show a couple of Spring service invocations.

Locate the entry point of your GWT application. The file should be named like {project_name}.java, in our case GWTSpring.java, and located under “client” subpackage or our main package. Alter the entry point class as shown below
package com.javacodegeeks.gwtspring.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.javacodegeeks.gwtspring.shared.dto.EmployeeDTO;
import com.javacodegeeks.gwtspring.shared.services.EmployeeService;
import com.javacodegeeks.gwtspring.shared.services.EmployeeServiceAsync;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class GWTSpring implements EntryPoint {
    /**
     * The message displayed to the user when the server cannot be reached or
     * returns an error.
     */
    private static final String SERVER_ERROR = "An error occurred while "
            + "attempting to contact the server. Please check your network "
            + "connection and try again. The error is : ";
    
    /**
     * Create a remote service proxy to talk to the server-side Employee service.
     */
    private final EmployeeServiceAsync employeeService = GWT
            .create(EmployeeService.class);

    /**
     * This is the entry point method.
     */
    public void onModuleLoad() {
        final Button saveOrUpdateButton = new Button("SaveOrUpdate");
        final Button retrieveButton = new Button("Retrieve");
        final TextBox employeeInfoField = new TextBox();
        employeeInfoField.setText("Employee Info");
        final TextBox employeeIdField = new TextBox();
        final Label errorLabel = new Label();

        // We can add style names to widgets
        saveOrUpdateButton.addStyleName("sendButton");
        retrieveButton.addStyleName("sendButton");

        // Add the nameField and sendButton to the RootPanel
        // Use RootPanel.get() to get the entire body element
        RootPanel.get("employeeInfoFieldContainer").add(employeeInfoField);
        RootPanel.get("updateEmployeeButtonContainer").add(saveOrUpdateButton);
        RootPanel.get("employeeIdFieldContainer").add(employeeIdField);
        RootPanel.get("retrieveEmployeeButtonContainer").add(retrieveButton);
        RootPanel.get("errorLabelContainer").add(errorLabel);

        // Focus the cursor on the name field when the app loads
        employeeInfoField.setFocus(true);
        employeeInfoField.selectAll();

        // Create the popup dialog box
        final DialogBox dialogBox = new DialogBox();
        dialogBox.setText("Remote Procedure Call");
        dialogBox.setAnimationEnabled(true);
        final Button closeButton = new Button("Close");
        // We can set the id of a widget by accessing its Element
        closeButton.getElement().setId("closeButton");
        final Label textToServerLabel = new Label();
        final HTML serverResponseLabel = new HTML();
        VerticalPanel dialogVPanel = new VerticalPanel();
        dialogVPanel.addStyleName("dialogVPanel");
        dialogVPanel.add(new HTML("<b>Sending request to the server:</b>"));
        dialogVPanel.add(textToServerLabel);
        dialogVPanel.add(new HTML("
<b>Server replies:</b>"));
        dialogVPanel.add(serverResponseLabel);
        dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
        dialogVPanel.add(closeButton);
        dialogBox.setWidget(dialogVPanel);

        // Add a handler to close the DialogBox
        closeButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                dialogBox.hide();
                saveOrUpdateButton.setEnabled(true);
                saveOrUpdateButton.setFocus(true);
                retrieveButton.setEnabled(true);
            }
        });

        // Create a handler for the saveOrUpdateButton and employeeInfoField
        class SaveOrUpdateEmployeeHandler implements ClickHandler, KeyUpHandler {
            /**
             * Fired when the user clicks on the saveOrUpdateButton.
             */
            public void onClick(ClickEvent event) {
                sendEmployeeInfoToServer();
            }

            /**
             * Fired when the user types in the employeeInfoField.
             */
            public void onKeyUp(KeyUpEvent event) {
                if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    sendEmployeeInfoToServer();
                }
            }

            /**
             * Send the employee info from the employeeInfoField to the server and wait for a response.
             */
            private void sendEmployeeInfoToServer() {
                // First, we validate the input.
                errorLabel.setText("");
                String textToServer = employeeInfoField.getText();

                // Then, we send the input to the server.
                saveOrUpdateButton.setEnabled(false);
                textToServerLabel.setText(textToServer);
                serverResponseLabel.setText("");

                String[] employeeInfo = textToServer.split(" ");
                
                long employeeId = Long.parseLong(employeeInfo[0]);
                String employeeName = employeeInfo[1];
                String employeeSurname = employeeInfo[2];
                String employeeJobTitle = employeeInfo[3];
                
                employeeService.saveOrUpdateEmployee(employeeId, employeeName, employeeSurname, employeeJobTitle, 
                        new AsyncCallback<Void>() {
                            public void onFailure(Throwable caught) {
                                // Show the RPC error message to the user
                                dialogBox
                                        .setText("Remote Procedure Call - Failure");
                                serverResponseLabel
                                        .addStyleName("serverResponseLabelError");
                                serverResponseLabel.setHTML(SERVER_ERROR + caught.toString());
                                dialogBox.center();
                                closeButton.setFocus(true);
                            }

                            public void onSuccess(Void noAnswer) {
                                dialogBox.setText("Remote Procedure Call");
                                serverResponseLabel
                                        .removeStyleName("serverResponseLabelError");
                                serverResponseLabel.setHTML("OK");
                                dialogBox.center();
                                closeButton.setFocus(true);
                            }
                        });
            }
        }
        
        // Create a handler for the retrieveButton and employeeIdField
        class RetrieveEmployeeHandler implements ClickHandler, KeyUpHandler {
            /**
             * Fired when the user clicks on the retrieveButton.
             */
            public void onClick(ClickEvent event) {
                sendEmployeeIdToServer();
            }

            /**
             * Fired when the user types in the employeeIdField.
             */
            public void onKeyUp(KeyUpEvent event) {
                if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    sendEmployeeIdToServer();
                }
            }

            /**
             * Send the id from the employeeIdField to the server and wait for a response.
             */
            private void sendEmployeeIdToServer() {
                // First, we validate the input.
                errorLabel.setText("");
                String textToServer = employeeIdField.getText();

                // Then, we send the input to the server.
                retrieveButton.setEnabled(false);
                textToServerLabel.setText(textToServer);
                serverResponseLabel.setText("");

                employeeService.findEmployee(Long.parseLong(textToServer),  
                        new AsyncCallback<EmployeeDTO>() {
                            public void onFailure(Throwable caught) {
                                // Show the RPC error message to the user
                                dialogBox
                                        .setText("Remote Procedure Call - Failure");
                                serverResponseLabel
                                        .addStyleName("serverResponseLabelError");
                                serverResponseLabel.setHTML(SERVER_ERROR + caught.toString());
                                dialogBox.center();
                                closeButton.setFocus(true);
                            }

                            public void onSuccess(EmployeeDTO employeeDTO) {
                                dialogBox.setText("Remote Procedure Call");
                                serverResponseLabel
                                        .removeStyleName("serverResponseLabelError");
                                if(employeeDTO != null)
                                    serverResponseLabel.setHTML("Employee Information Id : " + employeeDTO.getEmployeeId() + " Name : " + employeeDTO.getEmployeeName() + " Surname : " + employeeDTO.getEmployeeSurname() + " Job Title : " + employeeDTO.getJob());
                                else
                                    serverResponseLabel.setHTML("No employee with the specified id found");
                                dialogBox.center();
                                closeButton.setFocus(true);
                            }
                        });
            }
        }

        // Add a handler to send the employee info to the server
        SaveOrUpdateEmployeeHandler saveOrUpdateEmployeehandler = new SaveOrUpdateEmployeeHandler();
        saveOrUpdateButton.addClickHandler(saveOrUpdateEmployeehandler);
        employeeInfoField.addKeyUpHandler(saveOrUpdateEmployeehandler);
        
        // Add a handler to send the employee id to the server
        RetrieveEmployeeHandler retrieveEmployeehandler = new RetrieveEmployeeHandler();
        retrieveButton.addClickHandler(retrieveEmployeehandler);
        employeeIdField.addKeyUpHandler(retrieveEmployeehandler);
    }
}
As you can see, Spring service invocations are performed just like classic GWT service invocations, transparently to the client.

Finally locate the main web page for your project. The file should be named like {project_name}.html, in our case GWTSpring.html, and located under /war folder of our project. Alter the main web page as shown below
<!doctype html>
<!-- The DOCTYPE declaration above will set the    -->
<!-- browser's rendering engine into               -->
<!-- "Standards Mode". Replacing this declaration  -->
<!-- with a "Quirks Mode" doctype may lead to some -->
<!-- differences in layout.                        -->

<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

    <!--                                                               -->
    <!-- Consider inlining CSS to reduce the number of requested files -->
    <!--                                                               -->
    <link type="text/css" rel="stylesheet" href="GWTSpring.css">

    <!--                                           -->
    <!-- Any title is fine                         -->
    <!--                                           -->
    <title>Spring GWT Web Application Starter Project</title>
    
    <!--                                           -->
    <!-- This script loads your compiled module.   -->
    <!-- If you add any GWT meta tags, they must   -->
    <!-- be added before this line.                -->
    <!--                                           -->
    <script type="text/javascript" language="javascript" src="gwtspring/gwtspring.nocache.js"></script>
  </head>

  <!--                                           -->
  <!-- The body can have arbitrary html, or      -->
  <!-- you can leave the body empty if you want  -->
  <!-- to create a completely dynamic UI.        -->
  <!--                                           -->
  <body>

    <!-- OPTIONAL: include this if you want history support -->
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
    
    <!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
    <noscript>
      <div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
        Your web browser must have JavaScript enabled
        in order for this application to display correctly.
      </div>
    </noscript>

    <h1>Spring GWT Web Application Starter Project</h1>

    <table align="center">
      <tr>
        <td colspan="2" style="font-weight:bold;">Please enter employee info (id name surname job):</td>        
      </tr>
      <tr>
        <td id="employeeInfoFieldContainer"></td>
        <td id="updateEmployeeButtonContainer"></td>
      </tr>
      <tr>
      <tr>
        <td colspan="2" style="font-weight:bold;">Please enter employee id:</td>        
      </tr>
      <tr>
        <td id="employeeIdFieldContainer"></td>
        <td id="retrieveEmployeeButtonContainer"></td>
      </tr>
      <tr>
        <td colspan="2" style="color:red;" id="errorLabelContainer"></td>
      </tr>
    </table>
  </body>
</html>
To compile the application, right click on the project name and select Run As → Compile GWT Application

To deploy the web application just copy the /war folder in Apache – Tomcat “webapps” folder. You can change the name of the war folder to whatever you like, preferably rename it after the project name e.g. GWTSpring

To launch the application point your browser to the following address

http://localhost:8080/GWTSpring/

If all went well you should see your main web page. Two text boxes should be displayed each followed by a button. In the first text box you can save or update an employee to the database. Provide as input the id, the name, the surname, and a job description separated by a space character. Clicking on the “SaveOrUpdate” button the provided information will be stored to the database. For existing employee entries (same id) an update will be performed. The second text box is used to retrieve existing employee entries. Provide an employee id and click on the “Retrieve” button. If the employee exists you should see the employee id, name, surname and job description.

Few, that was a big tutorial!

You can download the project from here (required 3rd party libraries as described at the beginning are not included)


Hope you liked it


Justin


Related Articles :

Related Snippets :

79 comments:

  1. Does Spring take care of making sure that you don't get a LazyInitializationException, like if you had a collection or another object reference in there that wasn't initialized? I'd love it if it did that and took care of Spring Security exceptions automatically. Right now I use two projects to handle those: http://code.google.com/p/gwt-incubator-lib/ for Spring Security (although I had to modify the source for Spring Security 3, and Gilead (http://noon.gilead.free.fr/gilead/) for making sure the Hibernate object is clean to send down the wire. Unfortunately there's no integration between the two projects right now so I have to do Gilead's part manually. Although I haven't tried just passing the regular Spring Security exception down the line to see what happens.

    ReplyDelete
  2. For Spring service methods that perform retrieve (FIND) operations for objects that contain lazily initialized references you should use the @Transactional annotation, designating "NESTED" propagation type, in order for Spring to maintain the Hibernate session open for the entire method call. That way you will not get LazyInitializationException when accessing the lazy initialized fields.
    Nevertheless LazyInitializationException will be thrown, regardless of method annotations, if you perform a call to a method that assigns a member variable with the value of an object that contains a non initialized reference, and then you try to access the non initialized reference of that member variable on any subsequent call to the same or any other method. The latter is not a good practice and should be avoided. If you want to "cache" objects you should use a second level cache. We will post a tutorial on how to integrate Infinispan with Spring so stay tuned!

    ReplyDelete
  3. Nice work done here i wud really appericiate the work thanx very much i am also a java programmer

    ReplyDelete
  4. Hello!

    This is a great post/tutorial! Can I translate it to portuguese and post in another site(of course I'll link you, the original article)

    []'s

    ReplyDelete
  5. Take a look to Spring Roo. You can achieve same think but it takes you only half an hour to have a fully functional CRUD application, deployed to Google App Engine too.

    Br,
    Gabi

    ReplyDelete
  6. So using the @Transactional annotation will keep the Hibernate session open up through when it encodes it? What happens when it goes to encoding the object and at that point it's a PersistentBag or one of its other lazy loading classes? GWT doesn't know how to encode those, so you need something like Gilead to remove those and replace them with the regular Java List.

    ReplyDelete
  7. I have not gone through the tutorial but am looking forward to it. Another post mentioned Spring Roo. For anyone like me who is looking at the best group of technologies to do a one-man super website, the Spring Roo site noted:
    "SpringSource and Google are working together to combine the speed of development of Spring Roo with the power of the Google Web Toolkit (GWT) to build rich browser apps." .

    This tutorial could help developers who want to leverage Spring's new offering but don't know GWT.

    ReplyDelete
  8. spring4gwt version 0.0.1: I'm worried about its stability.

    ReplyDelete
  9. Interesting post, I would be interested to see if this works on App Engine too? I was able to run SPRING MVC on app engine, but had lot of issue with dependency jars.

    Anyways..excellent tutorial, 1 up on dzone for you.

    ReplyDelete
  10. I'm also concerned about spring4gwt. I've used it in the past, but it hasn't been updated in over a year.

    ReplyDelete
  11. Good work - admirable, in fact. But I think all you've demonstrated to me is just how much boilerplate and violation of the DRY principle there is in this architecture. All that baggage is going to make it difficult to explore and prototype new business requirements rapidly.

    What are your recommendations for starting with a simpler, more agile, architecture, and evolve into something like this one only if required?

    ReplyDelete
  12. Thank you all for your comments, it means a lot to us. Please forgive me for the late replies!

    kjordan, you are right GWT doesn't know how to encode Hibernate lazy initialization classes so either you have to use a tool like the one you mention or you could go with DTO mapping, which is our preferred method because it enforces separation of concerns. Furthermore several tools are out there that automate Java Bean mapping

    William, yes you can translate this tutorial and post it to another site. We would be grateful if you link back to us. One thing to notice though, due to Google's strict policy about duplicate content sites we would appreciate that you don't make an exact word by word translation of this article

    Toi and Niel, an upcoming article will provide information on how you can integrate a second level cache to this configuration. End to End (Multiple GWT clients invoke the retrieve method of the Spring back end service and wait for the response) stress tests will also be performed and the results will be posted. I am sure that we can discuss then about the performance and stability of this configuration and spring4gwt stability

    Sachin, We will extensively discuss Google's App Engine enabled configurations in future posts, so stay tuned!

    Dan, i am not sure that i am following you. This architecture enforces separation of concerns, you can create a project template in just about 15 minutes and from that point on all you have to do is implement services according to your business requirements. I honestly do not see any violation of the DRY principal in the architecture except maybe the part where you have to create the "normal" and the "asynchronous" interface of the same service implementation. On the other hand the proposed architecture is extremely flexible, pluggable, and above all fast. We will show you in future posts how to achieve carrier grade performance by plugging in the appropriate key technologies e.g second level cache, asynchronous messaging etc

    ReplyDelete
  13. @Justin

    Thank you. Sure I'll link this post, it is required by the readers!

    Congratulations for this great post.

    ReplyDelete
  14. Hi Justin,
    Search for the characters "Employee" across all the code fragments - how many times does it appear?

    From a domain perspective, there should be two occurrences - Employee, and EmployeeRepository. There is also the EmployeeRepositoryImpl which ties into the persistence store.

    These appear in your architecture, with EmployeeDTO is the domain object (though requiring it to be serializable is mixing in a bit of technology which violates your separation of concerns).

    I'd argue that EmployeeService and its implementation is all boilerplate, just forwarding onto underlying domain objects. Interestingly, I heard a podcast with Ramnivas Laddad (the Spring AOP guy) making the same point.

    Ditto for GWT front-end marshalling stuff. I'd even argue that the GUI layout, at least for a simple domain like this, is boilerplate too.

    I'm not arguing that you won't eventually need all this stuff, but maintaining all these layers will slow down development and inhibit experimentation as the domain model is developed.

    ReplyDelete
  15. Hi all:

    I think those are very good frameworks to make our life easy.
    But we found GAE isn't for production NOW because it auto-restarting will cause the performance and user experience very BAD.
    You can see more here: http://goo.gl/JAzS

    Thanks very much for this good article !!!

    ReplyDelete
  16. Hi all:

    I think every body who uses GAE should star this issue : http://goo.gl/juDy
    -->> PLEASE HELP !!

    Thank you very much~

    ReplyDelete
  17. Excellent and great effort to keep it simple!!!

    ReplyDelete
  18. Hey, I appreciate the article. I have a question: Why does the servlet mapping have to match the module name? The Spring4Gwt web site doesn't make mention of this, and it also seems that if you make your servlet take requests for "module.name.Module", then the request for module.name.Module/module.name.Module.nocache.js will be routed to it, which you wouldn't want. Thanks again!

    ReplyDelete
  19. Great tutorial, I found this very helpful. Simple and straight forward. Thanks.

    ReplyDelete
  20. Its very helpful. Thank you for sharing this article

    ReplyDelete
  21. This was extremely helpful, sorted out those awkward spring & hibernate dependency issues.

    ReplyDelete
  22. Thanx for this article!
    But I'm getting the following error (I also downloaded the sample project and it didn't launch)
    Error:
    org.datanucleus.exceptions.NucleusUserException: No available StoreManager found for the datastore URL key "". Please make sure you have all relevant plugins in the CLASSPATH (e.g datanucleus-rdbms?, datanucleus-db4o?), and consider setting the persistence property "datanucleus.storeManagerType" to the type of store you are using e.g rdbms, db4o
    at org.datanucleus.store.FederationManager.initialiseStoreManager(FederationManager.java:197)

    Any Ideas?

    Thanx in Advance!

    ReplyDelete
  23. HI

    I tried work on about example and i am getting below listed errors in GWTCompile , any idea ?


    Compiling module com.arif.GWSpring
    Validating newly compiled units
    [ERROR] Errors in 'file:/Users/ashaikw/Desktop/Spring/GWSpring/src/com/arif/client/EmployeeDAO.java'
    [ERROR] Line 4: The import javax.annotation cannot be resolved
    [ERROR] Line 15: PostConstruct cannot be resolved to a type
    [ERROR] Errors in 'file:/Users/ashaikw/Desktop/Spring/GWSpring/src/com/arif/client/EmployeeServiceImpl.java'
    [ERROR] Line 4: The import javax.annotation cannot be resolved
    [ERROR] Line 5: The import javax.annotation cannot be resolved
    [ERROR] Line 18: PostConstruct cannot be resolved to a type
    [ERROR] Line 22: PreDestroy cannot be resolved to a type
    [ERROR] Errors in 'file:/Users/ashaikw/Desktop/Spring/GWSpring/src/com/arif/client/JpaDAO.java'
    [ERROR] Line 3: The import java.lang.reflect cannot be resolved
    [ERROR] Line 20: ParameterizedType cannot be resolved to a type
    [ERROR] Line 20: ParameterizedType cannot be resolved to a type
    [ERROR] Line 20: The method getGenericSuperclass() is undefined for the type Class
    Scanning for additional dependencies: file:/Users/ashaikw/Desktop/Spring/GWSpring/src/com/arif/client/GWSpring.java
    Adding '30' new generated units
    Validating newly compiled units
    [WARN] Warnings in 'generated://1A1DEC8C90D3E20873979C15A7565A5C/com/arif/client/EmployeeService_TypeSerializer.java'
    [WARN] Line 36: Referencing deprecated class 'com.google.gwt.user.client.rpc.SerializableException'
    See snapshot: /var/folders/Th/ThtSzHzZETGUkTh7+Bt+nE+++TI/-Tmp-/EmployeeService_TypeSerializer6875772933575557936.java
    Compiling 6 permutations
    Compiling permutation 0...
    Compiling permutation 1...
    Compiling permutation 2...
    Compiling permutation 3...
    Compiling permutation 4...
    Compiling permutation 5...
    Compile of permutations succeeded
    Linking into /Users/ashaikw/Desktop/Spring/GWSpring/war/gwspring.
    Link succeeded
    Compilation succeeded -- 38.703s

    ReplyDelete
  24. Hello all, thank you for your comments!

    eXtr PM : This appears to be an issue with your persistence provider. I would suggest to Google the error since i have not used datanucleus myself and i cannot help you. It seams to be a configuration problem though.

    Arif Shaikh : You must use Java 1.5 and above for the example to work. The @PostConstruct annotation is introduced in java 1.5

    BRs

    Justin

    ReplyDelete
  25. THANKS MAN! THAT`S A GREAT TUTORIAL...

    ReplyDelete
  26. Hello Justin Cater,

    First i say thank you for your valuable post. But i am sorry i cant able to implement it successfully. I followed the steps what you said as it is. In Eclipse IDe the application is running, the page is displaying. But if i send any request to the server it throws an error.

    Moreover after building the war file and deployed it in Tomcat server the server never starts because the application throws log4j error(No classdef found error).

    Can you please guide me what i am doing wrong.

    Thanks
    Jaibabu

    ReplyDelete
  27. Hello Jai,

    Try to run the application on Tomcat. Check to see if log4j library is in your WEB-INF/lib directory

    BRs

    Justin

    ReplyDelete
  28. Good article! Example works great! I've implemented the same in my project. Seems stable. The problem I found is - how to work with session in EmployeeServiceImpl?

    ReplyDelete
  29. First, thanks for this tuttorial.

    Second, does anybody know why I get these when trying to run the example:
    Starting Jetty on port 8888
    [WARN] Failed startup of context com.google.gwt.dev.shell.jetty.JettyLauncher$WebAppContextWithReload@7aae3364{/,D:\projects\springworkspace\GWTSpring\war}
    org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: No suitable Log constructor [Ljava.lang.Class;@16a9255c for org.apache.commons.logging.impl.Log4JLogger (Caused by java.lang.NoClassDefFoundError: org/apache/log4j/Category) (Caused by org.apache.commons.logging.LogConfigurationException: No suitable Log constructor [Ljava.lang.Class;@16a9255c for org.apache.commons.logging.impl.Log4JLogger (Caused by java.lang.NoClassDefFoundError: org/apache/log4j/Category))
    at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:543)

    I have googled for the error but cannot make it work. Thanks!

    ReplyDelete
  30. I have found out the cause of the problem (see my previous entry). log4j jar needed to be added to the classpath.

    ReplyDelete
  31. Hello all,

    In one of my previous comments I stated that the @PostConstruct annotation is introduced in Java 1.5 which can be misleading, @PostConstruct and @PreDestroy annotations are introduced in JEE5 (Java 1.6), sorry for the inconvenience

    BRs

    Justin

    ReplyDelete
  32. Hi,

    i created another DTO with a OneToMany connection and if i try to start with mvn gwt:run i get the following exceptions:

    NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval

    Mmmh... what i can to solve this issue?

    ReplyDelete
  33. After another service which includes the error below began to appear, you know what can be?

    my structure is:
    server
    |-dao //My daos
    |-services //My impls
    shared
    |-dto //my dtos
    |-service //my service e asyncs

    WARNING: Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contaService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private br.com.bt.totengwt.server.dao.ContaDAO br.com.bt.totengwt.server.services.ContaServiceImpl.contaDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [br.com.bt.totengwt.server.dao.ContaDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}:
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [br.com.bt.totengwt.server.dao.ContaDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException

    ReplyDelete
  34. Hello all,

    Sorry for the late reply, I was on a short vacation!

    mfreitag, JPA does not support all available functionality Hibernate provides. the "orphanRemoval" is Hibernate specific. So either switch to plain Hibernate for your persistence provider or do not use the specific functionality if you want to go with JPA, you can always perform the "orphan removal" functionality by hand.

    Thadeu, Spring cannot autowire the "ContaDAO" to your "contaService". You should declare the dependent DAO in your "contaService" in a field using the same name as the one given to your DAO with the @Repository annotation. Additionally check that the DAO class is present in the build package.


    BRs

    Justin

    ReplyDelete
  35. Hi really nice tutorial. I'm little concern about early version of spring4gwt library, it looks like this project is not improved any more. BTW. orphanremoval is part of JPA2 specification (as element of OneToMany and OneToOne annotations) and it works with hibernate as jpa provider for me.

    ReplyDelete
  36. Nice tutorial. But why did you not include all deps in package? Alternatively putting urls for all of them (or creating maven project) would help a lot.

    Regards

    ReplyDelete
  37. I have the fallowing error while I deploy the war

    SEVERE: Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: Provider error. Provider: org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:290)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:418)
    Caused by: javax.persistence.PersistenceException: Provider error. Provider: org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider
    at javax.persistence.Persistence.createFactory(Persistence.java:176)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:112)
    at org.springframework.orm.jpa.LocalEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalEntityManagerFactoryBean.java:92)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
    ... 44 more
    Caused by: java.lang.NullPointerException
    at org.datanucleus.jpa.EntityManagerFactoryImpl.initialisePMF(EntityManagerFactoryImpl.java:452)
    at org.datanucleus.jpa.EntityManagerFactoryImpl.(EntityManagerFactoryImpl.java:355)
    at org.datanucleus.store.appengine.jpa.DatastoreEntityManagerFactory.(DatastoreEntityManagerFactory.java:63)
    at org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider.createEntityManagerFactory(DatastorePersistenceProvider.java:35)
    at javax.persistence.Persistence.createFactory(Persistence.java:172)
    ... 49 more

    ReplyDelete
  38. Awesome post man God bless you really :D


    hay "Kosa" i got the same error man her is the solution:-

    1- i added log4j in class path
    2- you must download this lib "c3p0"

    http://sourceforge.net/projects/c3p0/files/c3p0-bin/c3p0-0.9.1.2/c3p0-0.9.1.2.bin.tgz/download

    once you added it to you class path the application will run.

    jars in class path is as the folowing:-
    * the jars list described above
    * log4j-1.2.16.jar
    * c3p0-0.9.1.2.jar

    ReplyDelete
  39. Hi Justin,

    Thanks a ton for a very good article.
    But, inspite of following all the mentioned steps, i am not able to run it properly.
    I am facing the below two problems:
    1. How to run it directly from Eclipse IDE?
    2. If i run it with Tomcat, i am getting he following errors, which i could not solve even with google in a week of time:
    SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.javacodegeeks.gwtspring.server.dao.EmployeeDAO com.javacodegeeks.gwtspring.server.services.EmployeeServiceImpl.employeeDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.javacodegeeks.gwtspring.server.dao.EmployeeDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

    ReplyDelete
  40. i have the same error as Bhasker :(

    ReplyDelete
  41. From a beginner perspective, excellent tutorial.

    However, I have the same problem as robertalmalak and Bhasker Tiwari.

    ReplyDelete
  42. Hello Bhasker Tiwari, robertalmalak7 and Ivo

    The error that you are getting is strange indeed, especially if you have followed all mentioned steps as described in this tutorial.

    Please re-check what version of Spring framework you are using, clarify that The EmployeeDAO class is located in the produced war file and is annotated with @Repository("employeeDAO"), also verify that EmployeeServiceImpl class declares the private class variable for the employee DAO as shown below :

    @Autowired
    private EmployeeDAO employeeDAO;

    If all the aforementioned checks are valid then you should examine the error logs more carefully so as to pinpoint what is the exact cause of the problem.

    BRs

    ReplyDelete
  43. Very nice article, but is it possible to run the application in development mode with defaults's Jetty?

    ReplyDelete
  44. Justin... Nice guide, really!
    And - about this stupid problem with datanucleos! I found the solution.

    The problem is - seems everyone who has this problem - has more than one JPA libraries (jar files!) in your WEB-INF/lib. Or even you failed to copy hibernate3.jar there (like me!).

    Usual collection includes datanucleos, hibernate3 and maybe even openjpa! Again - in the same lib directory. As a result - Spring became crazy, and tries to load JPA - in alphabetical order (seems...). First is a datanucleos, therefore we are having these problems...

    Of course, you can go ahead and try to configure datanucleos - in the same persistence.xml. But it now must be for datanucleos JPA! (using keys like "datanucleus.storeManagerType" and so on...)

    I just removed the datanucleos jars, and placed hibernate3.jar on its place. Now I having completely different errors, but all of them are from hibernate (that was my goal actually :) )

    I am happy...

    ReplyDelete
  45. Nice article. For readable type-safe queries you might want to try Querydsl instead of String based JPAQL.

    ReplyDelete
  46. Hi,
    This is a very good tutorial, but i have a small problem when i launch Jetty.

    java.lang.ClassNotFoundException: org.spring4gwt.server.SpringGwtRemoteServiceServlet

    Anyone know how can i solve this ?

    web.xml :


    springGwtRemoteServiceServlet

    org.spring4gwt.server.SpringGwtRemoteServiceServlet



    Thanks

    ReplyDelete
  47. Hi,

    thanks a lot for this tutorial.

    just a question, i don't understand what is done by the function updateEmployee in EmployeeServiceImpl ? the other functions all use EmployeeDAO object to make a call on the database, but updateEmployee just create aa EmployeeDTO object, initialize the fields, and then ?? do nothing ? how is the update done on the database ? Isn't it a merge call missing there ?

    thanks

    Julien

    ReplyDelete
  48. Hello Julien,

    updateEmployee uses employeeDAO to find the appropriate EmployeeDTO, this action loads the EmployeeDTO object in Hibernate session (first level cache). That way and since the specific function is Transactional Hibernate will monitor the EmployeeDTO instance for changes so as prior commit Hibernate to perform an update operation against the database.

    BRs

    ReplyDelete
  49. Hello , Thanks alot for this tutorial ,
    i tried to create another classes like those (Employee) , they for developer ,
    i do all steps in this tutorial , but there is an error :(:(

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'developerService' defined in file .......\UMLDesigner\war\WEB-INF\classes\com\objetdirect\gwt\umldrawer\server\services\DeveloperServiceImpl.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available.

    help me please to solve it :)

    ReplyDelete
  50. Hello Bakhoum,

    It seems that you have to provide the CGLIB2 classes to your runtime environment!

    Brs

    ReplyDelete
  51. Hello ,
    Thanks Byron ,
    i have another error ,
    Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session

    This error release if there is a relation between Entity classes ( DTO ) ( many to many , ont to many ... )

    but when i remove this relation the error disappeared and i can retrieve all rows from table

    but when i put the relation , this error release ,
    i think the error not in hibernate but in How gwt treat with hibernate , i think this because of Serialization :

    [WARN] Exception while dispatching incoming RPC call
    com.google.gwt.user.client.rpc.SerializationException: java.lang.reflect.InvocationTargetException

    how i can let the relation and retrieve the rows without error ,

    note : i cannot use Fetch.Eager in the relation

    please help ASAP ,
    Best Regards

    ReplyDelete
  52. Hello Bakhoum,

    Please see our explanation on implementing the Spring CRUD service component, especially the part where @Transactional behavior is explained ... In all If you do not want to retrieve the "child" rows you have to create a "wrapper" object containing only the "parent" rows and return that to your client. On the other hand you could mark the service method as @Transactional designating "NESTED" propagation type in order for Spring to maintain Hibernate session open for the entire method call and perform a second query on the "child" table so as to retrieve the records and populate your "parent" objects!

    Hope that helped!

    BRs

    ReplyDelete
  53. Very good and simple example. Thanks. Question: You are using a JPA entity as a DTO which will then be shared by both Server and Client. I like this approach as I won't have to create a new DTO for client. But there are scenarios when you want to restrict information from client to access. For example, employeeSurname. Is it possible to do that using your approach of using the JPAEntity as a DTO? Thanks :)

    ReplyDelete
  54. Hi,
    thanks for this tutorial, I followed all the steps and everything worked right.

    But I got an error "Caused by: java.lang.NoSuchFieldError: NONE" when I execute HQL, for example when I call findAll() ( jpaDAO funtion).

    I only get this error when I execute HQL. If I call findById(K id) funtion it doesn't return me any error.

    I don't no why is this happening

    ReplyDelete
  55. Hello

    @j.singh.developer, I think that there is no way to do what you describe when you pass all information to the client. One way to overcome the issue is to create a "secured" DTO that will contain less information for certain clients.

    @franki, Please check your HQL syntax!

    BRs

    ReplyDelete
  56. Hi Justin

    Thank you for the article. I've spent some time to follow the tutorial and to build this application in my eclipse.

    Unfortunately the gwt4spring servlet does not find my employeeService :-(

    Here is the exception:

    15.04.2011 10:27:02 org.apache.catalina.core.ApplicationContext log
    SCHWERWIEGEND: Exception while dispatching incoming RPC call
    java.lang.IllegalArgumentException: Spring bean not found: employeeService
    at org.spring4gwt.server.SpringGwtRemoteServiceServlet.getBean(SpringGwtRemoteServiceServlet.java:96)
    at org.spring4gwt.server.SpringGwtRemoteServiceServlet.getBean(SpringGwtRemoteServiceServlet.java:55)
    at org.spring4gwt.server.SpringGwtRemoteServiceServlet.processCall(SpringGwtRemoteServiceServlet.java:31)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:243)
    at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
    at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1555)
    at java.lang.Thread.run(Thread.java:619)

    Any idea about this error?

    Thank you for your help
    Regards
    Artur

    ReplyDelete
  57. Hi Byron,
    I tried with
    - "FROM EmployeeDTO"
    - "SELECT h FROM EmployeeDTO h"
    - "SELECT r FROM EmployeeDTO r WHERE r.employeeName like ?1", "name"
    - "SELECT h FROM " + entityClass.getName() + " h"

    but I always got the error "Caused by: java.lang.NoSuchFieldError: NONE"

    I think it's not a problem of HQL syntax.

    Thank you for everything

    ReplyDelete
  58. Thank you for this very helpful post!

    :D

    ReplyDelete
  59. Unfortunately Justin, I am going to have to agree with Dan on this one. I too have written about GWT and Spring; however I find it violates the Separation of Concerns Principle by simple invasion OR the implied Spring Framework Interrupt of the GWT RPC Inner Framework. I am not quite convinced Spring is a good match for GWT for it degrades the RPC Channel Performance. Seeing that Spring is now working With GWT to produce a Spring Roo Layer...I will wait to see what unfolds. Here is the link to my discussion and concerns;

    http://maurice-johnson.blogspot.com/2011/03/gwt-hibernate-and-spring-framework.html

    ReplyDelete
  60. thanks for the post, I am getting the following exception when I deploy in the Tomcat I included
    hibernate3.jar and hibernate-jpa-2.0-api-1.0.0.Final.jar but still getting

    java.lang.NoSuchFieldError: SINGULAR_ATTRIBUTE
    at org.hibernate.ejb.metamodel.SingularAttributeImpl.getBindableType(SingularAttributeImpl.java:136) please give me some solutions about this.

    ReplyDelete
  61. hello,i have a error when i run my application GWTSpring in jetty.
    Error creating bean with name 'employeeDAO': Injection of autowired dependencies failed
    please help me .

    ReplyDelete
  62. I want to use Mysql database,can you help me to configure the persitence.xml file
    i need your help.

    ReplyDelete
  63. Hi all!

    Great tutorial and bravo for the good work Justin! really helps us to get started.

    I have a question though..

    What if I have already a Maven+Hibernate+Spring back-end running perfectly; and that I would like to add a GWT front-end? Since the whole project structure is different, is it even worth the consideration?
    I've looked into a lot of forums, discussion and tutorials but couldn't seem to find my answer.

    Thanks for any help :D

    ReplyDelete
  64. Hello, than you all for your comments.

    @MERCI: you can find numerous examples for configuring the "persistence.xml" to use MySQL. Just "google" for the result!

    @WenZ: Thanx!If you already have a back-end running Spring you could use our approach and implement *proxy* Spring services at the front-end that use Spring remoting to communicate with the back-end Spring services (provided that the back-end Spring services are exposed over Spring remoting channels)

    BRs

    ReplyDelete
  65. Great article. This has really helped me alot on integrating GWT/Spring/Hibernate.

    I'm now going to work out a custom example and will get back to this page if errors/remarks pop up.


    Bart

    ReplyDelete
  66. So, I finished my own example.

    I've done it a little bit different, no @Service/@Autowired annotations (I'm a fan of putting it into the application context xml).

    Also, I configured my Hibernate database stuff in another application-xml aswell (no persistence-xml) although I still use JPA for Entity-annotation.
    This also means my DAO extends HibernateDaoSupport instead of JpaDaoSupport.

    This all just custom taste (de gustibus et coloribus non disputandum est).


    However, I struggled for a while (too long!) with one issue:

    [WARN] 405 - GET /employee/gwt/clean/clean.css (127.0.0.1) 1486 bytes
    Request headers
    Host: 127.0.0.1:8888
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
    Accept: text/css,*/*;q=0.1
    Accept-Language: en,nl-be;q=0.7,fr-be;q=0.3
    Accept-Encoding: gzip, deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: keep-alive
    Referer: http://127.0.0.1:8888/Employee.html?gwt.codesvr=127.0.0.1:9997
    Response headers
    Content-Type: text/html; charset=iso-8859-1
    Content-Length: 1486


    Weird error, I'd say so... The application worked, but there was no CSS attached because of the error.

    Cause:
    GWT auto generates a css file to this location: war//gwt/clean/clean.css
    For me that became: war/employee/gwt/clean/clean.css

    Coincidentally, I mapped the Spring4GWT servlet as follows:


    spring4gwt
    org.spring4gwt.server.SpringGwtRemoteServiceServlet


    spring4gwt
    /employee/gwt/*



    So the spring4gwt servlet picked up the GET-request to the CSS and decided it could not be processed.


    Solution:
    Map the spring4gwt servlet to anything else:

    spring4gwt
    /employee/web/*




    Also, initially I struggled alot with getting my application to start up. There was a commons-logging.jar/log4j.jar problem.

    When I started up with Log4j in the WEB-INF/lib, it crashed saying it couldn't find some Log4j classes (although present).

    When I removed it from the classpath, the application booted, but the second some class tried to log, it crashed saying it couldn't find some other Log4j classes.

    Turned out my Eclipse had a duplicate log4j jar somewhere in its classpath, so when I removed it from WEB-INF/lib, it could launch the Jetty-server, but no class could log because the ClassLoader of the webapp didnt have the Log4J jar.
    And when I put the jar in the WEB-INF/lib it couldn't start due to duplicate jars.

    Solution: go Sherlock Holmes-style on your Eclipse installation and remove the Log4J jar it had referenced.


    Anyway, thanks again for the article, it was a really big help!

    Bart

    ReplyDelete
  67. It appears that in my above post the > and < tags were omitted.

    ReplyDelete
  68. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: javax.persistence.EntityManagerFactory com.javacodegeeks.gwtspring.server.dao.EmployeeDAO.entityManagerFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/datanucleus/jpa/exceptions/NoPersistenceXmlException



    Please Help

    I have only hibernate jpa in my lib and i have removed all other jpas'. how to resolve this.

    ReplyDelete
  69. Please, someone help me... I created a new Dao, and I've the following error

    Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: javax.persistence.EntityManagerFactory youjob.server.dao.OffertaLavoroDAO.entityManagerFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: MyPersistenceUnit] Unable to configure EntityManagerFactory

    I create the new Dao with the same procedure of the tutorial... Why it do that error? Please, someone help me...

    ReplyDelete
  70. First of all, thanks for this great tutorial! Helped me a lot!

    I got it all working and tried to make some adaptations to see if I understood everything well, when I encountered some strange behavior I don't understand at all.

    In the JpaDao class I thought it would be more logical to change the class constructor from:

    public abstract class JpaDAO extends JpaDaoSupport {

    to

    public abstract class JpaDAO extends JpaDaoSupport {

    and in EmployeeDao I did the same change in order:

    public class EmployeeDAO extends JpaDAO {


    Suddenly I get errors like the following:

    com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract com.javacodegeeks.gwtspring.shared.dto.EmployeeDTO com.javacodegeeks.gwtspring.shared.services.EmployeeService.findEmployee(long)' threw an unexpected exception: org.springframework.dao.InvalidDataAccessApiUsageException: Unknown entity: java.lang.Long; nested exception is java.lang.IllegalArgumentException: Unknown entity: java.lang.Long
    at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:385)
    ...


    Does anyone have any idea why I can't change the order of the declaration of the generic classes?

    Thanks in advance!

    ReplyDelete
  71. Ok suddenly In my previous post the generic stuff between the "larger" and "smaller" brackets gets deleted :(

    So I did the following:

    public abstract class JpaDAO{K, E} extends JpaDaoSupport {

    to

    public abstract class JpaDAO{E, K} extends JpaDaoSupport {

    and changed:

    public class EmployeeDAO extends JpaDAO{EmployeeDTO, Long} {

    Hope it's clear now, and apologies for the wrong brackets :)

    ReplyDelete
  72. ok... thank you so much Idc... but now I've another problem... My project sayd this...

    xception while dispatching incoming RPC call
    org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'org.springframework.transaction.interceptor.TransactionInterceptor#0' must be of type [org.aopalliance.aop.Advice], but was actually of type [org.springframework.transaction.interceptor.TransactionInterceptor]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:348)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor.getAdvice(AbstractBeanFactoryPointcutAdvisor.java:80)
    at org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry.getInterceptors(DefaultAdvisorAdapterRegistry.java:78)
    at org.springframework.aop.framework.DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(DefaultAdvisorChainFactory.java:61)
    at org.springframework.aop.framework.AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice(AdvisedSupport.java:482)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:188)
    at $Proxy32.toString(Unknown Source)
    at java.lang.String.valueOf(String.java:2826)
    at java.lang.StringBuilder.append(StringBuilder.java:115)
    at org.spring4gwt.server.SpringGwtRemoteServiceServlet.getBean(SpringGwtRemoteServiceServlet.java:60)
    at org.spring4gwt.server.SpringGwtRemoteServiceServlet.processCall(SpringGwtRemoteServiceServlet.java:31)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
    at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:324)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)

    some news?

    ReplyDelete
  73. Hello,

    i follow your example but i dont use HDBSQL instead of i use MySQL5.5 i got 3 layers, the Controllers, Service and DAO, each ones has annotated right, i mean, the Controller has the @Controller, the service @Service and the DAO has @Repository. In service layer i got @Transactional and never persist

    ReplyDelete
  74. Hi, I had the same problem. You have to download hibernate-validator-4.0.0.GA.jar (or another version, this one worked for me), and add it to WEB-INF/lib.

    ReplyDelete
  75. Alan GreenblattDec 25, 2011 11:50 PM

    Hi,

    Ran through your example and it ran like a charm, but I'm curious about how you can debug a Spring/GWT app.  I'd like to be able to run it in GWT's development mode, but when I try to do so, I get the following error:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: javax.persistence.EntityManagerFactory com.javacodegeeks.gwtspring.server.dao.EmployeeDAO.entityManagerFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: MyPersistenceUnit] Unable to configure EntityManagerFactory

    I'm sure I'm missing something simple.  Thanks.

    ReplyDelete
  76. Hi, thank you for this amazing tutorial.

    I am experiencing an odd problem. Everything seems to be OK but after tomcat starts up, and I open the browser, there are only texts, buttons are missing. I did no modification on the code, only difference is I am using Oracle 11g DB.

    Any help

    ReplyDelete
  77. Manuel Carrillo RodríguezJan 3, 2012 11:06 AM

    Hi, a great tutorial.

    But i'm having a problem when i try to deploy the application on Tomcat.

    I have always the same error message:

    GRAVE: Excepción enviando evento inicializado de contexto a instancia de escuchador de clase org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.annotation.internalAsyncAnnotationProcessor': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)


    I have reviewed the version of the JARs and all of them are the corrects.

    I have tried with the 'war' directory from you own eclipse project, but i have the same error message.

    So... any idea about why is failing?

    Thanks.

    ReplyDelete
  78. Ok, i have just found the solution.

    When we go to AOP Alliance web on Sourceforge, they have 2 versions of its JAR file.

    - aopalliance.jar
    - aopalliance-alpha1.jar

    I had the 'alpha1' file, because i thought that it was the only one version.

    With that file, your example doesn't work. With the 'aopalliance.jar' file, the example works.

    So, this can be a problem if I would want to make a web using all that you have written, because they have changed something important into their jar and the new versions won't work.

    ReplyDelete
  79. why I cant have java.util.Date field in Pojo class because throws me serialization exception 

    ReplyDelete

Related Posts Plugin for WordPress, Blogger...