Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当新的子实体被持久化时,父实体得到不必要的更新_Java_Hibernate_Jpa_Optimistic Locking - Fatal编程技术网

Java 当新的子实体被持久化时,父实体得到不必要的更新

Java 当新的子实体被持久化时,父实体得到不必要的更新,java,hibernate,jpa,optimistic-locking,Java,Hibernate,Jpa,Optimistic Locking,我们使用JPA实体和hibernate进行持久化。 我有一个计划实体和一个上报实体。当我创建一个新的升级并将其持久化时,计划也会以某种方式得到更新。此更新导致OptimisticLockException,并阻止进一步升级得到持久化。 下面是代码框架- @Entity @Table(name = "T_ESCLT") public class Escalation extends PersistentEntity { @Id @GeneratedValue(strategy =

我们使用JPA实体和hibernate进行持久化。 我有一个
计划
实体和一个
上报
实体。当我创建一个新的升级并将其持久化时,计划也会以某种方式得到更新。此更新导致
OptimisticLockException
,并阻止进一步升级得到持久化。 下面是代码框架-

@Entity
@Table(name = "T_ESCLT")
public class Escalation extends PersistentEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ESCLT_ID")
    private Integer id;

    @ReflectionCopy.Exclude
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CUST_RNEW_TASK_ID", nullable = false)
    private CustomerRenewalTask renewalTask;

    @ReflectionCopy.Exclude
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PLN_DSG_ID")
    private Plan plan;

public Escalation(CustomerRenewalTask task, Plan plan, String description) {
        Preconditions.checkNotNull(task);
        Preconditions.checkNotNull(description);

        this.renewalTask = task;
        this.plan = plan;
        this.description = description;
        this.creationTimestamp = DateUtils.currentTimestamp();
    }

Plan
CustomerRenewalTask
中未映射升级。 当我运行这个

@Transactional
    public Result persist() {
        CustomerRenewalTask customerRenewalTask = customerRenewalTaskDao.findById(2);
        Plan plan = planDao.findById(16);
        planDao.detach(plan);
        Escalation escalation = new Escalation(customerRenewalTask, plan, "My Escalation");
        escalationDao.persist(escalation);
        return ok();
    }
我在控制台日志中看到了这一点

DEBUG - insert into T_ESCLT (ESCLT_ID, OPTMSTC_LOCK_ID, ATRB_NM, CMNT_TXT, CRT_TS, ESCLT_DSCR, APP_LNK_TXT, PLN_DSG_ID, RT_BLCK_IND, CUST_RNEW_TASK_ID, RSLV_DT, RSLV_BY_USR_ID, RSLV_BY_USR_NM, ESCLT_STTS_CD, ESCLT_TYP_CD) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - update T_PLN_DSG set OPTMSTC_LOCK_ID=?, ASSOC_PLN_DSG_ID=?, BRTH_DT_RT_IND=?, PLN_EFF_DT=?, ELGBL_MBR_CNT=?, RNEW_PLN_DTL_XML=?, SUM_MBR_PRTCP_LIF_CNT=?, VLD_STTS_CD=?, PLN_NM=?, PLN_GRP_ID=?, PRNT_PLN_DSG_ID=?, PRTCP_MBR_CNT=?, PRTCP_PCT=?, PRTNR_PLN_DSG_ID=?, RT_CALC_XML=?, UW_VRFY_IND=?, SUM_VOL_AMT=? where PLN_DSG_ID=? and OPTMSTC_LOCK_ID=?

我不希望发布计划更新,因为
计划
上的任何内容都没有更改。我刚刚使用plan创建了一个升级。

阻止此更新发生的一种方法是为plan实体的各个属性指定update=false,但这样做可以防止在plan表上完全发生更新

请检查指定cascade=CascadeType.PERSIST是否可以解决您的问题

@ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.PERSIST)

您可能正在planDao中执行某些操作。分离(plan)以更新计划实体上的属性?请在
plan
中发布
plan
实体的映射以及相关方法的实现。根据定义,您必须对
plan
执行某些操作,这会导致Hibernate认为它“脏”需要在
flush()
时更新,我必须添加planDao.detach(plan);em().detach(plan)只执行哪个操作;这阻止了计划的更新,但解决方案在代码评审中被否决了。计划和升级具有单向的oneToMany映射,因此计划中没有升级属性。我在持续升级之前和之后打印了plan对象,我没有看到任何差异。我并没有做任何事情让计划变得肮脏,但hibernate却不这么认为。我在Escalation-@JoinColumn(name=“PLN\u DSG\u ID”)@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.PERSIST)私有计划中尝试了这一点;但是我在控制台日志中继续看到扩展插入和计划更新SQLs。