0

2011 年 5 月 11 日编辑:

我想这比下面的要差一些;在我部署的 QA 实例中,如果我只是多次刷新主仪表板,最终我的用户的多对多组关联将被删除。此时,服务器端只调用了select语句;希望我能通过这些最新的测试来缩小范围。

原来的:

大家好。我遇到了一个相当复杂的对象的问题;问题如下:当我将对象从客户端发送到服务器进行保存时,它似乎是随机清除关联对象上的多对多关系。更糟糕的是,在意识到该问题大约两个月后,我自己无法重现该问题。我将应用程序用于与 QA 组一起进行测试;他们每天都在使用该程序,两次输入新的和旧的应用程序。这个问题每天会出现多达 3 次。

我会尽我所能提供尽可能多的细节,非常感谢任何人看一看!

应用程序框架是 GWT 2.1 + Gilead + Hibernate 3 + MySQL InnoDB。我让 Hibernate 处理任何级联等,因此在 DB 中没有定义任何外键,尽管所有外键都在 DB 中设置。

以下是映射的一些摘录:

<hibernate-mapping>
 <class name="com.example.domain.Close" table="CLOSE">

 <many-to-one name="updateUser"
class="com.example.domain.User"
column="LAST_UPDATE_USER"/>
 </class>
</hibernate-mapping>

<hibernate-mapping>
  <class name="com.example.domain.User" table="USER" batch-size="25">
    <set name="groups" table="USER_GROUP" lazy="true" batch-size="25">
      <key column="USER_ID"/>
      <many-to-many column="GROUP_ID" class="com.example.domain.Group"/>
    </set>
  </class>
</hibernate-mapping>

<hibernate-mapping>
  <class name="com.example.domain.Group" 
    table="GROUP" batch-size="25">
    <set name="users" table="USER_GROUP" lazy="true" inverse="true">
      <key column="GROUP_ID"/>
      <many-to-many column="USER_ID" class="com.example.domain.User"/>
    </set>
    <set name="permissions" table="PERMISSION_GROUP" lazy="true" inverse="true">
    <key column="GROUP_ID"/>
    <many-to-many column="PERMISSION_ID" 
      class="com.example.domain.Permission"/>
    </set>

<hibernate-mapping>
  <class name="com.example.domain.Permission" 
      table="PERMISSION">
    <set name="groups" table="PERMISSION_GROUP" lazy="true">
      <key column="PERMISSION_ID"/>
      <many-to-many column="GROUP_ID" 
        class="com.example.domain.Group"/>
    </set>
  </class>
</hibernate-mapping>

保存对象很简单,只需调用 saveOrUpdate():

Session session = gileadHibernateUtil.getSessionFactory()
  .getCurrentSession();
session.beginTransaction();
try {
  session.saveOrUpdate(close);
} catch (Exception e) {
  e.printStackTrace();
  session.getTransaction.rollback();
}
session.getTransaction.commit();

return close;

Close 'updateUser' 是用户登录时加载的对象。它加载了相关的组和权限,因此系统可以授予/拒绝对应用程序模块的访问权限。我愿意

close.setUpdateUser(exampleApp.getUser()); 

在将对象发送回服务器之前。

应用程序中还有很多其他地方会发生这种操作,但不会导致不必要的副作用。它可能归结为与 Close 对象相关联的客户端代码的复杂性,或者更确切地说,是我的实现。

我花了很多时间翻阅官方的 Hibernate 文档,寻找可能相关的问题等,我想也许现在是寻求帮助的好时机。我必须坚持下去,但也许只是问会帮助我弄清楚。

我不确定现在还提供什么相关的。希望到目前为止这里的内容具有相关性!

感谢收听!

编辑

May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: insert into example_dev.RECENT_ITEM (OBJECT_TYPE, OBJECT_ID, DATE, USER_ID) values (?, ?, ?, ?)
May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.PERMISSION_GROUP where PERMISSION_ID=?
May  5 12:18:38 localhost last message repeated 19 times
May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.USER_GROUP where USER_ID=?
May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.USER_DESIGNATION where USER_ID=?

似乎删除是在此插入之后发生的。以前的操作都是选择。但是 User 中的任何内容都不应该从 RecentItem 级联。

4

1 回答 1

1

经过大量研究,我得出了一些结论并能够采取行动。首先,我在 Gilead 论坛上进行了大量搜索后了解到,它不再被积极维护。应该早点注意到。同时,我开始阅读有关 RequestFactory 的内容,经过几天的研究,我决定尝试迁移到这个。

这是一个相当大的项目,大约有 50 个领域对象,其中一些具有许多对象关联。从使用 Gilead + GWT RPC 到完全使用 RequestFactory,我花了大约 40 到 50 个小时来重写所有内容。我对由此产生的代码和结构变化感到非常满意。到目前为止,我不必为创建 DTO 代理对象而烦恼,我借此机会切换到 Hibernate Annotations,摆脱了映射文件。

有时重构代码以利用 RequestFactory 所需的获取/编辑/保存周期是很棘手的。它确实让我有机会改进一些代码。

好消息是,问题已经解决。不再神秘地删除多对多关联。我最好的猜测是我在 Gilead 中遇到了一个错误,或者我对它的使用不正确,或者我在迁移到 Annotations 时可能解决了一个问题。

我在学习 RequestFactory+Hibernate 时遇到了一些很棒的资源,其中很多是通过 StackOverflow(再次感谢!):

将 GWT RequestFactory 与 Objectify 一起使用- 很好地了解 RequestFactory 如何与后端交互,以及一些方法和样板来减少代码。

希望下面有更多链接..我仍然是菜鸟,所以我可以发布的超链接数量有限:)

我学到了很多东西,并且对 RequestFactory 越来越熟练了。我会尽我所能留意并在我认为可以的地方提供帮助。

感谢 StackOverflow!

于 2011-06-10T17:05:11.893 回答