ExtJS, Spring MVC 3 and Hibernate 3.5: CRUD DataGrid Example

This tutorial will walk through how to implement a CRUD (Create, Read, Update, Delete) DataGrid using ExtJS, Spring MVC 3 and Hibernate 3.5.

What do we usually want to do with data?

  • Create (Insert)
  • Read / Retrieve (Select)
  • Update (Update)
  • Delete / Destroy (Delete)

Until ExtJS 3.0 we only could READ data using a dataGrid. If you wanted to update, insert or delete, you had to do some code to make these actions work. Now ExtJS 3.0 (and newest versions) introduces the ext.data.writer, and you do not need all that work to have a CRUD Grid.

So… What do I need to add in my code to make all these things working together?

In this example, I’m going to use JSON as data format exchange between the browser and the server.

ExtJS Code

First, you need an Ext.data.JsonWriter:

 // The new DataWriter component.
    var writer = new Ext.data.JsonWriter({
        encode: true,
        writeAllFields: true

Where writeAllFields identifies that we want to write all the fields from the record to the database. If you have a fancy ORM then maybe you can set this to false. In this example, I’m using Hibernate, and we have saveOrUpate method – in this case, we need all fields to updated the object in database, so we have to ser writeAllFields to true. This is my record type declaration:

    var Contact = Ext.data.Record.create([
	{name: 'id'},
        name: 'name',
        type: 'string'
    }, {
        name: 'phone',
        type: 'string'
    }, {
        name: 'email',
        type: 'string'

Now you need to setup a proxy like this one:

    var proxy = new Ext.data.HttpProxy({
        api: {
            read : 'contact/view.action',
            create : 'contact/create.action',
            update: 'contact/update.action',
            destroy: 'contact/delete.action'

FYI, this is how my reader looks like:

    var reader = new Ext.data.JsonReader({
        totalProperty: 'total',
        successProperty: 'success',
        idProperty: 'id',
        root: 'data',
        messageProperty: 'message'  // <-- New "messageProperty" meta-data

The Writer and the proxy (and the reader) can be hooked to the store like this:

 // Typical Store collecting the Proxy, Reader and Writer together.
    var store = new Ext.data.Store({
        id: 'user',
        proxy: proxy,
        reader: reader,
        writer: writer,  // <-- plug a DataWriter into the store just as you would a Reader
        autoSave: false // <-- false would delay executing create, update, destroy requests until specifically told to do so with some [save] buton.

Where autosave identifies if you want the data in automatically saving mode (you do not need a save button, the app will send the actions automatically to the server). In this case, I implemented a save button, so every record with new or updated value will have a red mark on the cell left up corner). When the user alters a value in the grid, then a “save” event occurs (if autosave is true). Upon the “save” event the grid determines which cells has been altered. When we have an altered cell, then the corresponding record is sent to the server with the ‘root’ from the reader around it. E.g if we read with root “data”, then we send back with root “data”. We can have several records being sent at once. When updating to the server (e.g multiple edits). And to make you life even easier, let’s use the RowEditor plugin, so you can easily edit or add new records. All you have to do is to add the css and js files in your page:

<!-- Row Editor plugin css -->
	<link rel="stylesheet" type="text/css" href="/extjs-crud-grid/ext-3.1.1/examples/ux/css/rowEditorCustom.css" />
	<link rel="stylesheet" type="text/css" href="/extjs-crud-grid/ext-3.1.1/examples/shared/examples.css" />
	<link rel="stylesheet" type="text/css" href="/extjs-crud-grid/ext-3.1.1/examples/ux/css/RowEditor.css" />

<!-- Row Editor plugin js -->
	<script src="/extjs-crud-grid/ext-3.1.1/examples/ux/RowEditor.js"></script>

Add the plugin on you grid declaration:

    var editor = new Ext.ux.grid.RowEditor({
        saveText: 'Update'

    // create grid
    var grid = new Ext.grid.GridPanel({
        store: store,
        columns: [
            {header: "NAME",
             width: 170,
             sortable: true,
             dataIndex: 'name',
             editor: {
                xtype: 'textfield',
                allowBlank: false
            {header: "PHONE #",
             width: 150,
             sortable: true,
             dataIndex: 'phone',
             editor: {
                 xtype: 'textfield',
                 allowBlank: false
            {header: "EMAIL",
             width: 150,
             sortable: true,
             dataIndex: 'email',
             editor: {
                xtype: 'textfield',
                allowBlank: false
        plugins: [editor],
        title: 'My Contacts',
        height: 300,
		tbar: [{
            iconCls: 'icon-user-add',
            text: 'Add Contact',
            handler: function(){
                var e = new Contact({
                    name: 'New Guy',
                    phone: '(000) 000-0000',
                    email: 'new@loianetest.com'
                store.insert(0, e);
            iconCls: 'icon-user-delete',
            text: 'Remove Contact',
            handler: function(){
                var s = grid.getSelectionModel().getSelections();
                for(var i = 0, r; r = s[i]; i++){
            iconCls: 'icon-user-save',
            text: 'Save All Modifications',
            handler: function(){

Java code

Finally, you need some server side code.


package com.loiane.web;

public class ContactController  {

	private ContactService contactService;

	public @ResponseBody Map<String,? extends Object> view() throws Exception {


			List<Contact> contacts = contactService.getContactList();

			return getMap(contacts);

		} catch (Exception e) {

			return getModelMapError("Error retrieving Contacts from database.");

	public @ResponseBody Map<String,? extends Object> create(@RequestParam Object data) throws Exception {


			List<Contact> contacts = contactService.create(data);

			return getMap(contacts);

		} catch (Exception e) {

			return getModelMapError("Error trying to create contact.");

	public @ResponseBody Map<String,? extends Object> update(@RequestParam Object data) throws Exception {

			List<Contact> contacts = contactService.update(data);

			return getMap(contacts);

		} catch (Exception e) {

			return getModelMapError("Error trying to update contact.");

	public @ResponseBody Map<String,? extends Object> delete(@RequestParam Object data) throws Exception {



			Map<String,Object> modelMap = new HashMap<String,Object>(3);
			modelMap.put("success", true);

			return modelMap;

		} catch (Exception e) {

			return getModelMapError("Error trying to delete contact.");

	private Map<String,Object> getMap(List<Contact> contacts){

		Map<String,Object> modelMap = new HashMap<String,Object>(3);
		modelMap.put("total", contacts.size());
		modelMap.put("data", contacts);
		modelMap.put("success", true);

		return modelMap;

	private Map<String,Object> getModelMapError(String msg){

		Map<String,Object> modelMap = new HashMap<String,Object>(2);
		modelMap.put("message", msg);
		modelMap.put("success", false);

		return modelMap;

	public void setContactService(ContactService contactService) {
		this.contactService = contactService;


Some observations:

In Spring 3, we can get the objects from requests directly in the method parameters using @RequestParam. I don’t know why, but it did not work with ExtJS. I had to leave as an Object and to the JSON-Object parser myself. That is why I’m using a Util class – to parser the object from request into my POJO class. If you know how I can replace Object parameter from controller methods, please, leave a comment, because I’d really like to know that! :)

Service Class:

package com.loiane.service;

public class ContactService {

	private ContactDAO contactDAO;
	private Util util;

	public List<Contact> getContactList(){

		return contactDAO.getContacts();

	public List<Contact> create(Object data){

        List<Contact> newContacts = new ArrayList<Contact>();

		List<Contact> list = util.getContactsFromRequest(data);

		for (Contact contact : list){

		return newContacts;

	public List<Contact> update(Object data){

		List<Contact> returnContacts = new ArrayList<Contact>();

		List<Contact> updatedContacts = util.getContactsFromRequest(data);

		for (Contact contact : updatedContacts){

		return returnContacts;

	public void delete(Object data){

		//it is an array - have to cast to array object
		if (data.toString().indexOf('[') > -1){

			List<Integer> deleteContacts = util.getListIdFromJSON(data);

			for (Integer id : deleteContacts){

		} else { //it is only one object - cast to object/bean

			Integer id = Integer.parseInt(data.toString());


	public void setContactDAO(ContactDAO contactDAO) {
		this.contactDAO = contactDAO;

	public void setUtil(Util util) {
		this.util = util;

Contact Calss – POJO:

package com.loiane.model;

public class Contact {

	private int id;
	private String name;
	private String phone;
	private String email;

	public int getId() {
		return id;

	public void setId(int id) {
		this.id = id;

	@Column(name="CONTACT_NAME", nullable=false)
	public String getName() {
		return name;

	public void setName(String name) {
		this.name = name;

	@Column(name="CONTACT_PHONE", nullable=false)
	public String getPhone() {
		return phone;

	public void setPhone(String phone) {
		this.phone = phone;

	@Column(name="CONTACT_EMAIL", nullable=false)
	public String getEmail() {
		return email;

	public void setEmail(String email) {
		this.email = email;

DAO Class:

package com.loiane.dao;

public class ContactDAO implements IContactDAO{

	private HibernateTemplate hibernateTemplate;

	public void setSessionFactory(SessionFactory sessionFactory) {
		hibernateTemplate = new HibernateTemplate(sessionFactory);

	public List<Contact> getContacts() {
		return hibernateTemplate.find("from Contact");

	public void deleteContact(int id){
		Object record = hibernateTemplate.load(Contact.class, id);

	public Contact saveContact(Contact contact){
		return contact;

Util Class:

package com.loiane.util;

public class Util {

	public List<Contact> getContactsFromRequest(Object data){

		List<Contact> list;

		//it is an array - have to cast to array object
		if (data.toString().indexOf('[') > -1){

			list = getListContactsFromJSON(data);

		} else { //it is only one object - cast to object/bean

			Contact contact = getContactFromJSON(data);

			list = new ArrayList<Contact>();

		return list;

	private Contact getContactFromJSON(Object data){
		JSONObject jsonObject = JSONObject.fromObject(data);
		Contact newContact = (Contact) JSONObject.toBean(jsonObject, Contact.class);
		return newContact;
	private List<Contact> getListContactsFromJSON(Object data){
		JSONArray jsonArray = JSONArray.fromObject(data);
		List<Contact> newContacts = (List<Contact>) JSONArray.toCollection(jsonArray,Contact.class);
		return newContacts;

	public List<Integer> getListIdFromJSON(Object data){
		JSONArray jsonArray = JSONArray.fromObject(data);
		List<Integer> idContacts = (List<Integer>) JSONArray.toCollection(jsonArray,Integer.class);
		return idContacts;

If you want to see all the code (complete project will all the necessary files to run this app), download it from my GitHub repository: http://github.com/loiane/extjs-crud-grid-spring-hibernate

This was a requested post. I’ve got a lot of comments from my previous CRUD Grid example and some emails. I made some adjustments to current code, but the idea is still the same. I hope I was able answer all the questions. :)

Happy coding!

54 thoughts on “ExtJS, Spring MVC 3 and Hibernate 3.5: CRUD DataGrid Example

  1. Hi Loiane,

    this is a very good and clean post.

    I think it could be even better if you tried it in a more RESTful manner. And it is very close (code-wise) to what you have already. Just a few annotations to change and setup the store properly.

    To get the object into the controller without using your Util class you need the @RequestBody annotation. Then if you have Jackson configured as a message converter and client set header Content-Type as ‘application/json’ to the request, Spring does the job automatically.

    Check this post http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/


    1. @ Aggelos
      I tried to implement RESTful grid once, but because of that issue, I did not work. I’m going to try again.
      Thanks for the answer!

  2. @Abhaya

    If you already installed Git, just run this command:

    git clone git://github.com/loiane/extjs-crud-grid-spring-hibernate.git

  3. Hi Loiane, gr8 tutorial, although there are some things which did not understand like where from which part of the code in crud-grid.js does the code create.action gets called? i.e after store.save() how does it reach create.action?
    Secondly the modelMap returned from the controller where does it go to in the crud-grid.js
    Thanks in advance & Regards
    Mudassar Hakim

  4. Hola Loiane, yo recien comienzo con Extjs y me parece estupendo, gracias por el aporte de este tutorial, espero poder hacerte algunas consultas mas adelante, gracias.

  5. I’d like to pass some data from extjs to controllers view() method. When I change view method definition to :

    public @ResponseBody Map view(@RequestParam Object data)

    extjs shows error. Is it possible to pass some parameters (and read them) to the view method ?

    1. @mrs
      yes, but you have to use @requestbody instead of @requestparam.
      I still did not find out why we get error with requestparam.

  6. @Loiane
    I think I had the same problem with @RequestBody when I tried to use the restful api of both spring and extjs’ store.

    Ext’s JsonWriter by default posts data to the request’s body like this:
    data={property: value, property2: etc}

    Where ‘data’ is what you set as root in the extjs’ configuration. But Jackson (and Spring) try to unmarshal the object from the body in plain json like this:
    {property: value, property2: etc}

    So (I didn’t find any other way and) I created a PlainJsonWriter extending JsonWriter’s render method to send only the json… and everyone is happy now!


  7. @Aggelos, @Loiane

    use Writer and just set root to ” that will plain the requestBody to {..} instead of data={…}.

    Excellent article! Really clear! I agreed with a RESTfull example would help even more! Keep the good work!

  8. This is awesome!

    I am having trouble with hibernate for implementing a crud grid where the table has foreign keys using the same frameworks as the example. Any advice?

  9. nice article.
    @elmasse: Can you pls explain me more how to do this with @Requestbody annotation?


  10. İ ‘ve some problems that are firstly i dont connect my extjs project with mysql.And i dont know how to do ıt.
    second,i wanna use java codes( by hibernate) sql and extjs.i connect java-mysql but i dont link extjs how to do ıt???

    thx alot..

  11. Great work Loiane. I have a question.
    I modified writeAllFields to false. So that it should update modified field. I changed contact name. But it throws following error, “Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.loiane.model.Contact.email”. Why does it check email?
    Please let me know how to fix it.

  12. how are u writing the Ext JS code in eclipse. I found it difficult as I have to remember all the attributes, there is not auto help (like when you type the Ctrl+space normally it used to give the list of attributes or methods in eclipse). I dont find this for ext js (plugin for eclipse). 
    I tried with Sptket plugin for eclipse but it doesnt solve the problem, i still have to remember all the attributes and methods, 
    is anyone successful in this ??

    1. I use Sptket plugin for eclipse. And I keep the documentation opened in a browser as well.

    1. Hi Hades, you can download it from the github repository. On the right up corner, there is a download button.

  13. Pingback: extjstutorial.org
  14. Hello Loiane, Great post there. I tried downloading the code to run on JBOSS 5.1GA and cant seem to get it to start i get all sorts of errors related to hibernate.properties and mapping errors although i changed the Tomcat7 dependencies to JBOSS 5. any ideas what i need to do to make it run ?


  15. Noob here.Very nice job but i have a problem.When i run the project on server i get the error  message ERROR org.hibernate.util.JDBCExceptionReporter – Access denied for user ‘root’@’localhost’ (using password: YES). The problem is that i execute the sql file but i cant make any changes to the database from the grid.So i think is a Tomcat problem.Any idea?

  16. You opened my noobish fuckin eyes.Had to open db-config.xml in a text editor and type my root password.Thnx Loiane Greetings from Greece.

  17. Hi Loiane!!! Thank you very much!!!
    But, there are some things which did not understand like @mudassar…  
    I would greatly appreciate someone answer this:

    “which part of the code in crud-grid.js does the code create.action gets called? i.e after store.save() how does it reach create.action?Secondly the modelMap returned from the controller where does it go to in the crud-grid.js”

    Thanks, really!!

  18. Very good example! Do you have any plans in doing this same example using Extjs 4?
    I am new to Extjs and I am looking into using version 4. Thank you.

  19. super post!!!
    Hello @Loiane, thank you very much, really!But one doubt me, I’ve been watching the web page says @AndyC and don’t understand … ie, just change the @requestparam for @requestbody? and how to remove the part where you call util.class?
    if someone has done it, I would like to see how classes are modified.I’m new and i’m lost.
    Thank you very much if someone has it!!!!

  20. Super post!!!

    Hello @Loiane, thank you very much, really!But one doubt me, I’ve been watching the web page says @AndyC and I don’t understand … ie, just change the @requestparam for @requestbody? and how to remove the part where you call util.class?
    If someone has done it, I would like to see how classes are modified.I’m new and i’m lost.

    Thank you very much if someone has it!!!!

  21. Hi @Loiane!! One question in the Ext JS 4 example tha you’ve post without using the Utils.class, why do you use the ContactWrapper class? When you create, delete or edit a contact could you use “@RequestBody Contact data” instead of “@RequestBody ContactWrapper data” ?? If I change it the program give me an error. 
    Anyway I would like to know why is necessary to use the ContactWrapper class in order to get the parameter without errors. Thanks in advance!!


  22. Yeah!! I’ve seen this example. 
    What I would like to know if there is any way to instead of using the ContactWrapper use the Contact object directly without using the wrapper.. In your example the code for create action will be like this:

    public @ResponseBody Map create(@RequestBody Contact data) throws Exception {

    List contacts = contactService.create(data);
    return ExtJSReturn.mapOK(contacts);
    } catch (Exception e) {; return ExtJSReturn.mapError(“Error trying to create contact.”); } }
    The fact is that this does not work because jackson library doesn’t know who to parse it. Do you know which would be the solution? Or why I can’t use the Contact Bean directly? Because In the reader and writer of the store I’m indicating that the model is Contact.
    Thanks in advance again ;)!!

  23. Pingback: JavaPins

Comments are closed.