首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >hibernate正在更新中的选择。

hibernate正在更新中的选择。
EN

Stack Overflow用户
提问于 2011-08-04 18:07:00
回答 3查看 812关注 0票数 1

我有一个遗留的网络应用程序,我正在维护。它最初是Java1.4,但我已经将其编译为Java5。我们正在使用Spring+Hibernate。我还没有使用注解。我现在还是坚持XDoclet。在它中,我有一个对象图,如下所示:

工作1:m业务1:m活动1:m交易

这些事务不是J2EE事务。我们只是记录从一个活动到另一个活动的工作流程。

在HttpRequest#1中,我更新了几个活动并创建了一个新事务。然后在HttpRequest#2中,我重新显示整个作业。现在我看到的是通常用于作业、操作和活动的SELECT语句,但是接下来我看到了一些用于事务的更新语句。事实证明,这些更新正在将事务恢复到以前的状态,从而丢弃最新的更新。

为什么Hibernate要这么做?

根据请求,下面是.hbm.xml文件:

代码语言:javascript
复制
<hibernate-mapping>
  <class name="ActivityTransaction" table="imed_if_move_transactions"
    lazy="false" mutable="true">
    <cache usage="nonstrict-read-write" />
    <id name="id" column="IF_MOVE_TRANSACTION_ID" type="java.lang.Long">
      <generator class="sequence">
        <param name="sequence">IMED_IF_MOVE_TRANSACTIONS_S</param>
      </generator>
    </id>
    <property name="activityActionKey" type="java.lang.String"
      update="true" insert="true" column="ACTIVITY_ACTION_KEY" />
    <property name="approvalStatus" type="int" update="true"
      insert="true" column="APPROVAL_STATUS" />
    <property name="authorizedBy" type="java.lang.Long" update="true"
      insert="true" column="AUTHORIZATION_ID" />
    <many-to-one name="authorizedByUser"
      class="UserModel" cascade="none"
      outer-join="false" update="false" insert="false" not-found="ignore"
      fetch="select" column="AUTHORIZATION_ID" />
    <property name="date" type="java.util.Date" update="true"
      insert="true" column="JOA_TRANSACTION_DATE" />
    <many-to-one name="from"
      class="JobOpActivity" cascade="none"
      outer-join="false" update="true" insert="true" fetch="select"
      column="FM_JOB_OP_ACTIVITY_ID" />
    <property name="fromIntraActivityStepType" type="java.lang.Integer"
      update="true" insert="true" column="FM_INTRAACTIVITY_STEP_TYPE" />
    <property name="fromIntraOperationStepType" type="java.lang.Integer"
      update="true" insert="true" column="FM_INTRAOPERATION_STEP_TYPE" />
    <property name="fromOperationSeqNum" type="java.lang.Integer"
      update="true" insert="true" column="FM_OPERATION_SEQ_NUM" />
    <many-to-one name="job" class="Job"
      cascade="none" outer-join="false" update="true" insert="true" fetch="select"
      column="WIP_ENTITY_ID" />
    <property name="operationEndDate" type="java.util.Date"
      update="true" insert="true" column="OP_END_DATE" />
    <property name="operationStartDate" type="java.util.Date"
      update="true" insert="true" column="OP_START_DATE" />
    <many-to-one name="organization" class="Organization"
      cascade="none" outer-join="false" update="true" insert="true" fetch="select"
      column="ORGANIZATION_ID" />
    <property name="processingStatus" type="java.lang.String"
      update="true" insert="true" column="PROCESS_FLAG" />
    <property name="quantity" type="int" update="true" insert="true"
      column="TRANSACTION_QUANTITY" />
    <property name="reasonId" type="java.lang.Long" update="true"
      insert="true" column="REASON_ID" />
    <property name="reference" type="java.lang.String" update="true"
      insert="true" column="REFERENCE" />
    <property name="scrapAccountId" type="java.lang.Long" update="true"
      insert="true" column="SCRAP_ACCOUNT_ID" />
    <property name="spsaId" type="java.lang.Long" update="true"
      insert="true" column="SPSA_ID" />
    <many-to-one name="to"
      class="JobOpActivity" cascade="none"
      outer-join="false" update="true" insert="true" fetch="select"
      column="TO_JOB_OP_ACTIVITY_ID" />
    <property name="toIntraActivityStepType" type="java.lang.Integer"
      update="true" insert="true" column="TO_INTRAACTIVITY_STEP_TYPE" />
    <property name="toIntraOperationStepType" type="java.lang.Integer"
      update="true" insert="true" column="TO_INTRAOPERATION_STEP_TYPE" />
    <property name="toOperationSeqNum" type="java.lang.Integer"
      update="true" insert="true" column="TO_OPERATION_SEQ_NUM" />
    <property name="typeId" type="java.lang.Long" update="true"
      insert="true" column="TRANSACTION_TYPE_ID" />
    <property name="webKeyEntryId" type="java.lang.String"
      update="true" insert="true" column="WEB_KEY_ENTRY_ID" />
    <property name="issueMaterial" type="true_false" update="true"
      insert="true" column="MATERIAL_ISSUE" />
    <property name="createDate" type="java.util.Date" update="true"
      insert="true" column="CREATION_DATE" />
    <property name="createdBy" type="java.lang.Integer" update="true"
      insert="true" column="CREATED_BY" />
    <property name="lastUpdateDate" type="java.util.Date" update="true"
      insert="true" column="LAST_UPDATE_DATE" />
    <property name="lastUpdatedBy" type="java.lang.Integer"
      update="true" insert="true" column="LAST_UPDATED_BY" />
  </class>
</hibernate-mapping>

下面是一个事务设置示例:

代码语言:javascript
复制
<bean id="moldingActivitiesService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager" ref="etrack2ProviderTransactionManager"/>
  <property name="target" ref="moldingActivitiesServiceTarget"/>
  <property name="transactionAttributes">
    <props>
      <prop key="*">PROPAGATION_REQUIRED</prop>
    </props>
  </property>
</bean>
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-11 19:34:53

好了,终于找到问题了。这里有一个更完整的流程:

我有Controller C1、Manager M1、Manager M2和Persister P1。正如我前面所述,M1和M2使用TransactionProxyFactoryBean管理事务。

方法A()调用M1.methodB(),后者调用P1.methodC()

  • C1.methodA(),然后调用M2.methodD(),后者调用M1.methodE(),后者调用P1.methodF().

看到问题了吗?

当M1.methodD调用M1.methodE()时,就会发生这种情况。我认为发生的情况是,由于M1和M2都是事务管理的,因此创建了两个事务,每个调用一个事务。这两项交易都是为了争夺系统的真实状态,而这两个交易都没有一个真正的赢家。

票数 0
EN

Stack Overflow用户

发布于 2011-08-04 19:18:59

来自Google http://ajava.org/online/hibernate3api/org/hibernate/FlushMode.html上的Hibernate Javadoc文档

汽车

代码语言:javascript
复制
public static final FlushMode AUTO 

有时会在执行查询之前刷新会话,以确保查询永远不会返回陈旧状态。这是默认的刷新模式。

您在JPA管理的实体上所做的每一项修改都是在持久上下文中完成的。这意味着Hibernate假设您在实体中修改的内容是安全的。因此,当您从同一个实体或相关实体中选择数据时,Hibernate将更改的一致性置于其他所有内容之上。因此,它会刷新,然后执行读取,以正确地反映您的更改。如果你不想有这种行为,你可以做两件事:

  • 禁用自动提交(我更喜欢它,但它是某种JPA约定,所以请下决心)。这种方法的缺点是,您必须根据您的配置手工完成更多的工作。好处是,每件事都要显化得多,魔法更少的
  • 改变了您首先收集需要的数据的代码。此外,这将使您的代码更加简洁。因为它就像每个人都能理解的基本的计算机科学模式:输入,计算,输出。这就是默认模式不能工作的原因。

编辑:关于如何在不使用注释的情况下最好地使用Spring的PlatformTransactionManager,我建议使用TransactionTemplate:http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/transaction.html#tx-prog-template将您的PlatformTransactionManager (Hibernate)注入到那里,并使用它从事务处理中抽象出来。

票数 2
EN

Stack Overflow用户

发布于 2011-08-04 18:27:03

取决于您的FLUSHMODE,您将看到这一点,因为每当您执行查询时,hibernate通常都会猜测它是否应该刷新以获得干净和一致的读取。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6946361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档