gwt 2.0.x gilead hibernate tutorial

UPDATE: 05.08.2013

If you came to this blog in order to learn how to manage Data transfer from Server layer to the GWT layer, please note that since 2010 GWT team has introduced new and comfortable way to do that. The mechanism is called Request Factory and you can read more about it here:  http://www.gwtproject.org/doc/latest/DevGuideRequestFactory.html.

If you run to any problems you can check my other blog post where I explain how the most common update/save workflow works in Request Factory: exciting life of entity proxies.

UPDATE: 14.10.2010 – official GWT 2.1 .RC release with Request Factory

When I was writing this tutorial, there was no official GWT support for sending Entities from server to client side.  Since GWT 2.1.rc is officially released the suggested way to connect JPA or Hibernate with GWT is to use RequestFactory. Read more on : http://code.google.com/webtoolkit/doc/trunk/DevGuideRequestFactory.html.
If you are interested in gilead with gwt 2.0.4 anyway you can still read my tutorial:)
afd

GWT Gilead tutorial – what for?

Writing client code in GWT is very nice way to produce user layout fast and easy. But when you need to get some data from the database.. debate begins. GWT has some restrictions which don’t allow you to use every framework in  every way you want. Especially if you are using object relational mapping frameworks you need to make some workaround if you want to send your entities to the client side.  E.g. you can use Data Transfer Objects (DTO) – which in some cases may be good because they encourage you to send only this information which you really need to show. But still you have to take care of cloning all your entities..
Another solution is using Gilead framework, which takes care about serializing your entities also handling lazy loaded parameters. There are some examples on the web how to use it but I haven’t found any example with the newest version of gilead and gwt as well with annotated hibernate entities.  That is why I have decided to share the steps I have made to configure such a project.
I will present you already working GWT project example which doesn’t have Gilead support. Then I will describe steps you need to take to add Gilead framework to it. If you are lazy you can just download the final version of project which is configured and ready to go.

I) I assume you already know :

  • GWT basics
  • how to create widgets on client side,
  • how to make Remote Procedure Calls (via GWT RPC),
  • usage of GEP plugin to configure and manage your project in Eclipse
  • Hibernate,  mapping entities with Annotations
  • HSQL database

II) Technologies used:

III) Tools used:

  • Eclipse Galileo
  • Google Eclipse Plugin (GEP)
  • HSQL database

IV) Tutorial

A) getting simple GWT project

    1. Download this project : http://dl.dropbox.com/u/11217505/StudentManagerWithoutGilead.zip . Unpack it and import to Eclipse. This project goal is to manage professors with their list of students. Project consists of elements:
      • Domain classes: Professor and Student. Notice that Professor has a List of students which is annotated as OneToMany with fetch=FetchType.LAZY.
      • Services: StudentManagerService, StudentManagerServiceAsync, StudentManagerServiceImpl. Created with Gwt-rpc mechanism. They are using DAO classes for saving and retrieving data about professors and students from the database.
      • DAOs – this is the direct layer which handles the database.
      • Client code is written in one class StudentManager. User see three panels where he can add professor, student and connect student with a professor.
      • StudentManager.gwt.xml is configuring gwt compiler.
      • configuration files :
        • hibernate.cfg.xml is configuring connection to database and hibernate behaviour
        • log4j.properties is configuring logging appenders.
  • Compile project with GWT-compiler gwt icon
    1. start the HSQL database
    2. Run project in debug mode debug
    3. Open application in the browser ( using the link given by debugger console) go to web site
    4. Try to add student, then to add professor. The third panel should contain 2 combo box lists with students and professors you have added. Choose professor and a student from lists and then click “Add connection” button. This operation should fail on the server. After trying to add this connection I have got exception:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
  • Now we will add Gilead framework to this simple GWT project in order to have possibility to serialize our entities without problems.

B) Adding Gilead  support.

    1. download Gilead.
    2. Unpack the downloaded archive.
    3. In the archive you will find set of libraries. Copy specified jars into your war/WEB-INF/lib folder :
beanlib-5.0.2beta.jar
beanlib-hibernate-5.0.2beta.jar
gilead-core-1.3.2.1839.jar
gilead-hibernate-1.3.2.1839.jar
gilead4gwt-1.3.2.1839.jar
cglib-2.2.jar
asm-3.2.jar
Those libraries should also appear in your project build-path. They should be visible as “Web App Libraries”. If you don’t see them – add them manually via project properties -> configure build path.
  • Edit “StudentManager.gwt.xml” file adding line:
<inherits name='net.sf.gilead.Gilead4Gwt' />
This will inform gwt compiler that it should also compile Gilead classes.
  • Make entity classes Professor and Student extend the net.sf.gilead.pojo.gwt.LightEntity.
import net.sf.gilead.pojo.gwt.LightEntity;
@Entity
public class Professor extends LightEntity implements Serializable{
After adding this inheritance you must compile your project with Gwt-compiler.gwt icon
  • Now you have to change Service implementation class: StudentManagerServiceImpl
  • Make this class extend the net.sf.gilead.gwt.PersistentRemoteService
  • You also need to initialize so-called BeanManager. This is class which is helping with serialization of your objects.
You can do it like in example shown below:
   public class StudentManagerServiceImpl extends PersistentRemoteService implements
		StudentManagerService {

	StudentDao studentDao = new StudentDao();
	ProfessorDao professorDao = new ProfessorDao();

	private Log log = LogFactory.getLog(StudentManagerServiceImpl.class);

	private static HibernateUtil gileadHibernateUtil = new HibernateUtil();

	public StudentManagerServiceImpl() {
		initHibernateUtil();
	}

	private void initHibernateUtil() {
		log.debug("initializing hibernate persistance for gilead");
		gileadHibernateUtil.setSessionFactory(AbstractDao.getSessionFactory());
		PersistentBeanManager persistentBeanManager =  GwtConfigurationHelper
				.initGwtStatelessBeanManager(gileadHibernateUtil);
		setBeanManager(persistentBeanManager);
		log.debug("persistentBeanManager initialized");
	}
     ...
  }
There are many possibilities to configure your services. You can read more about it here: http://noon.gilead.free.fr/gilead/index.php?page=documentation
  1. Run your project one more time.  Go to the browser and try to add professor – student connection.  If you have made all the steps correctly you shouldn’t see any  LazyInitializationException and have no more problems with serialization:)

You can download already configured last version of project example from here:

http://dl.dropbox.com/u/11217505/StudentManager.zip

V) Links

 

Advertisements

15 Responses to gwt 2.0.x gilead hibernate tutorial

  1. Zoltan Balazs says:

    Thank you for this tutorial. I found it really helpful!

  2. ximu says:

    Thank you for this helpful tutorial! It was very helpful to understand the first steps with Gilead.
    But now I want to use Gilead in my application on JBoss with EJB3. You said, you configured this already? I’m really interested in how you solved this. Can you send me a sample-project? Or did you already post a tutorial?
    Thank you, ximu

    • fascynacja says:

      @ximu: yes I did it, but didn;t have motivation and time to prepare some small example:) Anyway you can try to split this project into 3 parts: ear, ejb and web. Put business part into ejb and if you will got into any troubles you can ask me for help.. I can try to make simple project for you but you will have to wait a bit 😉

      • ximu says:

        @fascynacja: thanks for the quick reply! I solved it already. My project-structure is almost the same. But my problem was, that my entity-classes were in an extra project and gwt-module. Without Gilead i only had to include this module in the main gwt.xml-file. But now i had to include a jar-file with the entity-classes in the WEB-INF-folder of the webproject.

  3. fymo says:

    thank you, that was very helpful. It solved a very big problem I was facing, now I can go on with my project 🙂

  4. gbougeard says:

    Hi,
    I’m trying to plug gilead in an EAR containing EJB + WAR (gwt). My project is mavenized and I don’t understand why gilead-core.jar is not packaged in my ejb jar.
    Do you ahev some lead?

  5. gbougeard says:

    in fact it should be normal that I don’t have the gilead-core in my ejb.jar (as my friend google found) because dependencies are in my ear.
    But my problem is the following when I want to deploy the ear :
    Exception while loading the app : EJB Container initialization error java.lang.NoClassDefFoundError: net/sf/gilead/pojo/gwt/LightEntity at java.lang.ClassLoader.defineClass1(Native Method)

    gilead-core.jar is well in my ear, so maybe a classloader issue but I’m not yet a guru to fix it :/

  6. Syrine says:

    Hi, thank you for this helpful tutorial.

    When I used it in my application, I have an error with the plugin “Plugin failed to connect to Development Mode server at 127.0.0.1:9997” Error in the browser and the error in the console of Eclipse “nvalid version number “2.1” passed to external.gwtOnLoad(), expected “2.0”; your hosted mode bootstrap file may be out of date; if you are using -noserver try recompiling and redeploying your app”. This error appears when I used GWT 2.03 but when I use GWT 2.1 or + the application run, but I can’t excute my RCP service.

    Can I fix this issue please.

    Thank you

  7. sytra says:

    Hi, I followed your tutorial step by step, the application runs but when I launch a RPC service, it lead me directly ton OnFailure method, and in the Eclipse Console, I have this message :

    java.lang.NoClassDefFoundError: Could not initialize class [my_GWT_package].dao.PrjHome
    at [my_GWT_package].server.OroTimeSheetServiceImpl.(OroTimeSheetServiceImpl.java:25)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at java.lang.Class.newInstance0(Class.java:355)
    at java.lang.Class.newInstance(Class.java:308)
    at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
    at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:463)
    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)

    PrjHome : it’ the Project DAO class (contains the CRUD method, exactly like the tutorial)
    How can I solve this issue please.
    Thank you

  8. Hector says:

    Hello Agata.
    Thanks for your tutorial. It has been very helpful. I wonder if you know about how to solve this issue.. Please help, I do not want to change to RequestFactory GWT mode, at least not by now….

    I am having a null pointer exception when trying to get a List of Entities that have other entities as attributes:

    The entity class:

    public class Medico extends LightEntity implements IsSerializable {

    private static final long serialVersionUID = 1L;
    private Integer codigoMedico;
    private Categoria categoria;
    private Especialidad especialidad;
    private EstadoPersona estadoPersona;
    private String nombre;
    private String apellido;
    private Date cumple;
    private String telefonoCelular1;
    private String foto;
    private String email;
    ……….. with its getters and setters…

    __________________________________________________________________
    The RPC service class:

    public class MedicoServiceImpl extends PersistentRemoteService implements
    MedicoService{

    private static final long serialVersionUID = -4878654706801670097L;
    private Log logger = LogFactory.getLog(this.getClass());

    public MedicoServiceImpl() {
    HibernateUtil gileadHibernateUtil = new HibernateUtil();
    gileadHibernateUtil.setSessionFactory(AbstractDao.getSessionFactory());
    PersistentBeanManager persistentBeanManager = GwtConfigurationHelper
    .initGwtStatelessBeanManager(gileadHibernateUtil);
    setBeanManager(persistentBeanManager);
    logger.debug(“persistentBeanManager initialized”);
    }

    @Override
    public List getAll() {
    return MedicoQuerier.getAll();
    }

    @Override
    public Medico getByID(Integer codigo) {

    …………. other methods……….

    The exception:

    [java] DEBUG [net.sf.gilead.core.hibernate.HibernateUtil] Marking class java.lang.NullPointerException as not persistent
    [java] DEBUG [net.sf.gilead.core.PersistentBeanManager] Not persistent instance, clone is not needed : java.lang.NullPointerException
    [java] DEBUG [net.sf.gilead.gwt.GileadRPCHelper] Clone took 4 ms.

    Every domain entity has its extends and implements as it should as well as every service implementation has the gilead code lines in its constructor. It is a strange error because this does not happen with other entities. For other use cases with simpler entities (do not have any domain entities as attributes) it works fine.

    Thank you and regards,
    Hector

  9. annonymous says:

    hi, please change your image.

  10. Maxime says:

    Just awesome ! Your tutorial resolve my problème very quickly. Thank you for this post !

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: