GWT + Hibernate + Dispatch

When you create a portal, it is often the main function of the BackEnd is to work with the database. As a rule now, no one uses basic and not very comfortable for writing Statement's, and instead use ORM frameworks. In the case of GWT this framework is likely to become Hibernate, since on the server we Java. I'm not the first came up with the idea that it is extremely convenient and easy it would be to convey not the individual data and the whole POJO(persistent objects) used by Hibernate. So I created a service that returns to the client part of POJO. POJO has prosledovali from Serializable. Launch the app and get this here is the exception:

Caused by: com.google.gwt.user.client.rpc.SerializationException: Type 'org.hibernate.collection.PersistentSet' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.
at com.google.gwt.user.server.rpc.impl.StandardSerializationPolicy.validateSerialize(StandardSerializationPolicy.java:83)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:591


Not immediately clear what went wrong. The fact is that once an object becomes persistent, it takes the number of changes required to work with Hibernate. For instance, a normal Set change PersistentSet. Because of this, the browser has no way to deserialize an object sent to it, under any circumstances.

integration

As I said, I am by far not the first who wanted to pass a POJO on the client side, and as a result are not the first who faced a similar problem. On the Internet you can find three major solutions to this problem and integrate Hibernate with GWT.
• DTO(Data Transfer Objects) – you can create your own objects to transfer the data to the client part of the application are not persistent, but otherwise contains all the same fields as in POJO used by you.
• Use of library Dozer for mapping objects, This library automatically copies data from one object to another. For it to work properly, the Objects must contain the same fields and getters and setters are named in accordance with the JavaBean notation.
• A library of Gilead also known as hibernate4gwt.
The first option is fairly trivial, and I'm not going to consider it as well, and the second, which is just a little more advanced the first. If you are interested in the second option all the necessary information about the library you can find on the official website dozer.sourceforge.net

Gilead

Much more interesting is the last option, which I'll tell you. Glead — a library that provides the ability to freely transfer POJOs between the client and server part of the application. When using this library on the server between Java server and client, you receive a layer called PersistentBeanManager. If you pass an object from the server to the client, the PBM automatically clones the POJO in the same client object, while ignoring all LazyInitiaslization and replacing another field not initialized to NULL. While maintaining POJOs in memory. To reverse the merge you work into trunk PBM client object stored in the POJO and sends it to the server POJO with the already updated data.
To use this incredibly convenient miracle you must add the library project. To connect the module in gwt.xml to presledovat all POJO LightEntity, and a servlet instead of RemoteServiceServlet PersistantRemoteService. May be worth it to just describe the process and finish on this article, but as you can see in the title includes the word Dispatch. The fact is that many with the aim of re-use of code use pattern programming Dispatch with a library of gwt-dispatch based on dependency injection with Guice. If you use this library in your project is not a service class. You use a standard service GuiceStandardDispatchServlet, which is sewn inside the library of gwt-dispatch. In order to get around this I'm slightly built and rebuilt the library.

First we need to rebuild the library of gwt-dispatch. For this use any mercurial client and take away resources from the repository. hg clone code.google.com/p/gwt-dispatch
Create a project in the IDE which you are comfortable, where all this and shoving. I'm using Eclipse. Further the project came together I added in .classpath the following libraries
• gilead-core-1.3.2.1839.jar
• gliead-hibernate-1.3.2.1839.jar
• glead4gwt-1.3.2.1839.jar
• gin-1.5-post-gwt-2.2.jar
• guice-3.0.jar
• hibernate.jar
• org.springframework.beans-3.1.2.RELEASE.jar
• org.springframework.context-3.1.2.RELEASE.jar
• org.springframework.web-3.1.2.RELEASE.jar
Open the class net.customware.gwt.dispatch.server.standard.AbstractStandardDispatchServlet and made a few changes for the correct work of our library:
the
public abstract class extends AbstractStandardDispatchServlet
PersistentRemoteService implements StandardDispatchService {

public AbstractStandardDispatchServlet() {
HibernateUtil hibernateUtil = new HibernateUtil();

SessionFactory sf;
Configuration conf = new Configuration();
conf.configure();
conf.getProperties();
sf = conf.buildSessionFactory();

hibernateUtil.setSessionFactory(sf);

PersistentBeanManager persistentBeanManager = new PersistentBeanManager();
persistentBeanManager.setPersistenceUtil(hibernateUtil);

StatelessProxyStore sps = new StatelessProxyStore();
sps.setProxySerializer(new GwtProxySerialization());
persistentBeanManager.setProxyStore(sps);

setBeanManager(persistentBeanManager);
}

public <R extends Result > R execute(Action<R> action)
throws DispatchException {
try {
Dispatch dispatch = getDispatch();

if (dispatch == null)
throw new ServiceException("No dispatch found for servlet '"
+ getServletName()
+ "' . Please verify your server-side configuration.");

return dispatch.execute(action);
} catch (RuntimeException e) {
log("Exception while executing" + action.getClass().getName()
+ ": "+ e.getMessage(), e);
throw new ServiceException(e);
}
}

/**
* 
* @return The Dispatch instance.
*/
protected abstract Dispatch getDispatch();

}

After all the changes made can easily build the library and add it to the project(or you can just replace .class file in old). Also need to add the following library
• beanlib-5.0.5.jar
• beanlib-hibernate-5.0.5.jar
• com.springsource.net.sf.cglib-2.2.0.jar

Included in gwt.xml gilead to the client side know about our LightEntity
the
<inherits name="net.sf.gilead.Gilead4Gwt" />

And inherit all POJO LightEntity as shown below
the
@Entity
@Table(name = "CARD")
public class Card extends LightEntity implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CARDID", columnDefinition = "BIGINT NOT NULL AUTO_INCREMENT")
private long cardId;

@Column(name = "CARDNUMBER")
private String cardNumber;

@ManyToOne
@JoinColumn(name = "USERID", insertable = false, updatable = false, nullable = false)
private User user;

@Column(name = "ACTIVATED")
private Integer activated;

public Long getCardId() {
return cardId;
}

public void setCardId(Long cardId) {
this.cardId = cardId;
}

public String getCardNumber() {
return cardNumber;
}

public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

public Integer getActivated() {
return activated;
}

public void setActivated(Integer activated) {
this.activated = activated;
}

}


In General, all. Now you can easily pass your persistent objects between server and client parts of GWT application while continuing to use Dispatch.
Article based on information from habrahabr.ru

Comments

Popular posts from this blog

Powershell and Cyrillic in the console (updated)

Active/Passive PostgreSQL Cluster, using Pacemaker, Corosync

Automatic deployment ElasticBeanstalk using Bitbucket Pipelines