您如何在不同的项目中将 JPA 对象与 GWT 一起使用?

Posted

技术标签:

【中文标题】您如何在不同的项目中将 JPA 对象与 GWT 一起使用?【英文标题】:How do you use JPA objects with GWT in a different project? 【发布时间】:2010-12-30 16:07:10 【问题描述】:

我是 GWT 的新手,我正在设置一个项目来保存复杂应用程序的 UI 部分。 JPA 数据对象是在一个单独的项目中使用 MyBatis 生成的 POJO 定义的。一旦我手动修改 JPA 对象以包含“实现可序列化”(这是我需要解决的一个单独问题),构建过程中的 gwtc 步骤将无法继续,因为它需要 JPA 对象的源代码,但可以找不到他们。

我已经创建了“核心”项目的 jar 文件,以便它包含源 .java 文件,但这不起作用。我尝试在 gwtc ant java 调用中添加一个类路径元素。

如何在将 JPA 对象定义在单独的项目中的同时编译我的 UI 项目?

错误:

Buildfile: /Users/user/source/user_interface/build.xml

libs:

javac:

gwtc:
     [java] Compiling module org.mysite.ui
     [java]    Validating newly compiled units
     [java]       [ERROR] Errors in 'file:/Users/user/source/user_interface/src/org/mysite/ui/client/MyService.java'
     [java]          [ERROR] Line 21: No source code is available for type org.mysite.core.model.Person; did you forget to inherit a required module?
     [java]       [ERROR] Errors in 'file:/Users/user/source/user_interface/src/org/mysite/ui/client/MyServiceAsync.java'
     [java]          [ERROR] Line 19: No source code is available for type org.mysite.core.model.Person; did you forget to inherit a required module?
     [java]       [ERROR] Errors in 'file:/Users/user/source/user_interface/src/org/mysite/ui/client/presenter/MainTabPresenter.java'
     [java]          [ERROR] Line 75: No source code is available for type org.mysite.core.model.Person; did you forget to inherit a required module?
     [java]    Scanning for additional dependencies: file:/Users/user/source/user_interface/src/org/mysite/ui/client/MyApp.java
     [java]       Computing all possible rebind results for 'org.mysite.ui.client.MyService'
     [java]          Rebinding org.mysite.ui.client.MyService
     [java]             Checking rule <generate-with class='com.google.gwt.user.rebind.ui.ImageBundleGenerator'/>
     [java]                [ERROR] Unable to find type 'org.mysite.ui.client.MyService'
     [java]                   [ERROR] Hint: Previous compiler errors may have made this type unavailable
     [java]                   [ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly
     [java]    [ERROR] Errors in 'file:/Users/user/source/user_interface/src/org/mysite/ui/client/MyApp.java'
     [java]       [ERROR] Line 23:  Failed to resolve 'org.mysite.ui.client.MyService' via deferred binding
     [java]    [ERROR] Cannot proceed due to previous errors

BUILD FAILED
/Users/user/source/user_interface/build.xml:39: Java returned: 1

Total time: 26 seconds

蚂蚁gwtc目标:

  <target name="gwtc" depends="javac" description="GWT compile to javascript (production mode)">
    <java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
      <classpath>
        <pathelement location="src"/>
        <pathelement location="../core/src"/>
        <path refid="project.class.path"/>
      </classpath>
      <!-- add jvmarg -Xss16M or similar if you see a ***Error -->
      <jvmarg value="-Xmx256M"/>
      <arg line="-war"/>
      <arg value="web"/>
      <!-- Additional arguments like -style PRETTY or -logLevel DEBUG -->
      <arg line="$gwt.args"/>
      <arg value="org.mysite.ui.MyApp"/>
    </java>
  </target>

【问题讨论】:

【参考方案1】:

GWT 一直有这个问题。

我过去采用的方法是在其他 JAR 中创建一个 .gwt.xml 模块,包括 JPA POJO,并将 JPA 注释类放在“emul”javax.persistence 文件夹中。这当然不适用于许多使用延迟获取的提供商,因此需要 Gilead(如此处的另一个答案所述)。

另一种方法是制作 JPA 对象的副本,然后在通过 RPC 发送之前将它们推平

幸运的是,GWT 2.1 已经解决了这个问题。使用Entity proxies 并请求工厂。效果很好。

【讨论】:

您能否提供更多关于如何获取 .gwt.xml 在数据项目中编译然后与 Web 项目集成的详细信息?对于我的情况,这似乎是一个理想的解决方案。 所以,我将 gwt.xml 添加到数据项目中,构建了 jar,将其复制到另一个项目,并在 Web 项目中添加了“继承”。由于它位于类路径中,因此 gwt 会找到 DataModel.gwt.xml 文件,并且知道类。我已经非常接近这个解决方案了! 我将 gwt.xml 移到了 web 项目中,但在与数据项目中的数据文件夹相同的 java 包中。我将数据项目的 jar 作为单独的类和源 jar 发布。 GWT 检查 gwt.xml 定义的包的类路径并在 Web 项目中编译它们。像臭臭的一样工作。 抱歉,这么久才回复,已经赔钱了。首先,如果您想在生产环境中包含另一个 JAR 模块,请确保所有客户端源的 .java 文件都在其中。不要将 GWT 的开发模式与生产部署混淆。您还有其他问题吗? 不——我创建了两个罐子——一个带有类,一个只带有源文件。效果很好!【参考方案2】:

    要么使用新的 GWT 2.1 RequestFactory / EntityProxy 方法,要么

    最好放弃 JPA 并使用 Objectify 或 Twig。

我们使用 Objectify,因为 JPA 不适合 Datastore。 JPA 在创建时考虑到了基于 SQL 的关系数据库,而 GAE 数据存储则完全不同。

Google 将 JPA 层移植到 Datastore 以吸引开发人员,假装 Datastore 只是一个普通的旧 SQL 关系数据库。一旦项目变大,这会在他们的脸上爆炸。

如果您想使用 AppEngine,您确实需要了解数据存储区的权衡。 JPA 在这里不是帮您忙。

【讨论】:

EntityProxy 是非常新的,我还没有使用它,但可能很快就会使用它,因为我一直计划为此目的编写一个生成器。如果您打算使用 GAE,那么您关于为 Objectify 放弃 JPA 的评论是一个好主意,但如果您将基于 SQL 的数据库与 Glassfish 或 JBoss 等 J2EE 服务器结合使用,那么坚持使用 JPA 和 EntityProxy 将是更好的方法。这也假设您正在使用 GWT-RPC。我编写了一个类似于 EntityProxy 的生成器,但用于 JSON 通信。 JPA 存在并且正在使用中,因此此时不能选择切换。 EntityProxy 似乎希望我注释生成的类。同样,不要使用我想在客户端使用的外部生成的简单数据类。有什么建议吗?【参考方案3】:

如果您想将 POJO 序列化为 GWT,最好的选择是使用 Gilead http://noon.gilead.free.fr/gilead/

你在 POJO 上要做的就是扩展 LightEntity 并实现 Serializable

本教程非常直接地介绍了如何设置 RPC。

【讨论】:

以上是关于您如何在不同的项目中将 JPA 对象与 GWT 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

GWT JPA - 无法反序列化响应

GWT 2.2 + JPA 问题

如何在 Spring MVC (JPA) 中将实体对象列表转换为页面对象?

使用 GWT RPC 序列化在 POST 中将对象从客户端发送到服务器

如何在 GWT RPC 中将异常从服务器传递到客户端

域对象是不是与 JPA 实体相同?