gpt4 book ai didi

java - hibernate 在选择中间更新

转载 作者:行者123 更新时间:2023-11-30 05:00:22 25 4
gpt4 key购买 nike

我有一个正在维护的旧版 Web 应用程序。它最初是 Java 1.4,但我已将其编译为 Java5。我们使用Spring+Hibernate。我还没有使用注释。我现在坚持使用 XDoclet。其中,我有一个如下所示的对象图:

作业 1:m 运营 1:m Activity 1:m 事务

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

在 HttpRequest#1 中,我更新了几个 Activity 并创建了一个新事务。然后在 HttpRequest#2 中,我重新显示整个作业。此时我看到的是作业、操作和 Activity 的常见 SELECT 语句,但随后我看到了事务的一些 UPDATE 语句。事实证明,这些更新将事务恢复到之前的状态,丢弃了最新的更新。

Hibernate 到底为什么要这么做?

根据要求,这是 .hbm.xml 文件:

<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>

这是一个交易设置示例:

<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>

最佳答案

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

AUTO

public static final FlushMode AUTO 

The Session is sometimes flushed before query execution in order to ensure that queries never return stale state. This is the default flush mode.

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

  • 禁用自动提交(我更喜欢它,但这是某种 JPA 约定,所以请自行决定)。这种方法的缺点是您必须根据您的配置手动执行更多操作。好处是,一切都更加明确,不再那么神奇
  • 更改您首先收集所需数据的代码。这也会使你的代码更加简洁。因为它的工作原理就像每个人都理解的基本计算机科学模式:输入、计算、输出。你把这些东西混在一起了,这就是默认模式不起作用的原因。

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

关于java - hibernate 在选择中间更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6946361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com