GWT + Hibernate +ディスパッチ

ポータルを作成するとき、非常に多くの場合、BackEndの主な機能はデータベースを操作することです。 原則として、現在はだれも通常の文を使用することはなく、Statementの記述にあまり便利ではありません。これに代わり、ORMフレームワークを使用しています。 GWTの場合、サーバー上にJavaがあるため、このフレームワークはおそらくHibernateになります。 個々のデータではなく、Hibernateが使用するPOJO(永続オブジェクト)全体を転送することは非常に便利で簡単だと思ったのは初めてではありませんでした。 そこで、サービスを作成し、POJOのクライアント部分に戻りました。 POJOはSerializableから継承しました。 アプリケーションを起動すると、次の例外が発生します。



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









何が悪いのかすぐにはわかりません。 実際、オブジェクトが永続化されるとすぐに、Hibernateが機能するために必要な一連の変更が必要になります。 たとえば、通常のSetはPersistentSetに変更されます。 このため、どのような状況でも、ブラウザーは送信されたオブジェクトを非シリアル化できなくなります。



統合方法


すでに述べたように、私はクライアント側にPOJOを転送したいと思った最初の人ではなく、その結果、同様の問題に直面した最初の人でもありません。 インターネットでは、この問題を解決し、HibernateをGWTに統合する3つの主な方法を見つけることができます。

•DTO(データ転送オブジェクト)-永続的ではないが、使用しているPOJOと同じフィールドをすべて含む、アプリケーションのクライアント部分にデータを転送するための独自のオブジェクトを作成できます。

•Dozerライブラリを使用してオブジェクトをマッピングする-このライブラリは、あるオブジェクトから別のオブジェクトにデータを自動的にコピーします。 正しい操作のために、オブジェクトには、JavaBean表記に従って命名された同じフィールドとゲッターとセッターが含まれている必要があります。

•hibernate4gwtとも呼ばれるGileadライブラリの使用。

最初のオプションは非常に簡単であり、私はそれを考慮しませんし、2番目のオプションは最初に少し高度になります。 2番目のオプションに興味がある場合は、公式サイトdozer.sourceforge.netでライブラリに関するすべての必要な情報を見つけることができます。



ギレアデ


さらに興味深いのは最後のオプションです。これについては、これから説明します。 Gleadは、アプリケーションのクライアント部分とサーバー部分の間でPOJOを自由に転送する機能を提供するオープンライブラリです。 サーバーでこのライブラリを使用すると、Javaサーバーとクライアントの間にPersistentBeanManagerというレイヤーが表示されます。 サーバーからクライアントにオブジェクトを送信するとき、PBMはすべてのLazyInitiaslizationを無視し、まだ初期化されていないフィールドをNULLに置き換えながら、POJOを同様のクライアントオブジェクトに自動的に複製します。 同時に、メモリにPOJOを保存します。 リターン実行時に、PBMはPOJOが格納されているクライアントオブジェクトを点滅させ、既に更新されたデータとともにPOJOサーバーに転送します。

この信じられないほど便利な奇跡を使用するには、プロジェクトライブラリを追加する必要があります。 必要なモジュールをgwt.xmlに接続し、すべてのPOJO LightEntityを継承し、RemoteServiceServlet PersistantRemoteServiceの代わりにサーブレットを使用します。 おそらく、このプロセスを簡単に説明してこの記事を終了する価値があるでしょうが、記事のタイトルにあるように、Dispatchという単語があります。 実際、多くの人が、Guiceライブラリを使用してコードを再利用する依存関係注入に基づいて、gwt-dispatchライブラリでDispatchプログラミングパターンを使用しています。 このようなライブラリを使用する場合、プロジェクトにはサービスクラスがありません。 gwt-dispatchライブラリ内に配線されている標準のGuiceStandardDispatchServletサービスを使用します。 これを回避するために、このライブラリをわずかに再構築しました。



ギレアデ+派遣


まず、gwt-dispatchライブラリを再構築する必要があります。 このために、水銀のクライアントを使用し、リポジトリからリソースを取得します。 hg clone code.google.com/p/gwt-dispatch





IDEでプロジェクトを作成します。このプロジェクトでは、これらすべてを配置するのにより便利です。 Eclipseを使用しています。 次に、プロジェクトを進めるために、次のライブラリを.classpathに追加しました

•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

net.customware.gwt.dispatch.server.standard.AbstractStandardDispatchServletクラスを開き、ライブラリが正しく機能するようにいくつかの変更を行います。

 public abstract class AbstractStandardDispatchServlet extends 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(); }
      
      





すべての変更が完了したら、ライブラリを安全にビルドしてプロジェクトに追加できます(または、古いものの.classファイルを単純に置き換えることができます)。 次のライブラリをプロジェクトに追加する必要もあります

•beanlib-5.0.5.jar

•beanlib-hibernate-5.0.5.jar

•com.springsource.net.sf.cglib-2.2.0.jar



glead.xmlにgileadを含めて、クライアント側がLightEntityについて知るようにします

 <inherits name="net.sf.gilead.Gilead4Gwt" />
      
      





以下に示すように、すべてのPOJO LightEntityに継承されます

 @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; } }
      
      





一般的に、すべて。 これで、Dispatchの使用を継続しながら、GWTアプリケーションのサーバー部分とクライアント部分の間で永続オブジェクトを安全に転送できます。




All Articles