簡體   English   中英

存儲 spring JPA 存儲庫在保存之前找到要變量的數據?

[英]store spring JPA repository find data to variable before save?

我想在保存 spring JPA 存儲庫 object 之前存儲它。

在 function 更新中,我想將舊記錄數據存儲到dbDomain但在repository.save(updated)之后 dbDomain 突然更改為新的更新數據。

有誰知道如何解決這個問題? 謝謝

package com.test.admintool.userauth.services;

import java.text.SimpleDateFormat;
import java.util.*;

import com.test.admintool.engine.common.AdminToolFunction;
import com.test.admintool.engine.common.AuditTrailMessage;
import com.test.admintool.engine.common.CopyUtil;
import com.test.admintool.engine.service.AdminService;
import com.test.admintool.engine.service.AuditTrailEventService;
import com.test.admintool.engine.utils.SecurityUtil;
import com.test.admintool.userauth.entity.User;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.GenericTypeResolver;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;

import com.test.admintool.engine.AdminEntity;
import com.test.admintool.engine.exception.EntityNotFoundException;
import com.test.admintool.engine.repository.AdminRepository;
import com.querydsl.core.types.Predicate;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.Table;

@Slf4j
public abstract class AdminServiceImpl<T extends AdminEntity<T>> implements AdminService<T> {

    private static final String AUDIT_ACTION_CREATE = "CREATE";
    private static final String AUDIT_ACTION_UPDATE = "UPDATE";
    private static final String AUDIT_ACTION_DELETE = "DELETE";
    private final AdminRepository<T> repository;

    private final AuditTrailEventService auditTrailEventService;

    protected AdminServiceImpl(AdminRepository<T> repository, AuditTrailEventService auditTrailEventService) {
        this.repository = repository;
        this.auditTrailEventService = auditTrailEventService;
    }

    public T get(Long id) throws EntityNotFoundException {
        return repository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException(String.format("Product %s not found", id)));
    }

    @Transactional
    public T update(T updated) throws EntityNotFoundException {
        T dbDomain = get(updated.getId());
        T updatedData = repository.save(updated);
        produceAuditMessageUpdate(dbDomain, updatedData, AUDIT_ACTION_UPDATE);
        return updatedData;
    }
}

我假設您將一個分離的實體實例傳遞給update方法,並且在進入該方法時啟動了一個新事務(通過 spring 事務性 aop 代理)。
(否則, dbDomain條目將從 hibernate 一級緩存解析到傳遞的實體實例updated ,因此不會有任何屬性差異。)

當將updated分離實例傳遞給save方法時,實體管理器會將其合並到持久化上下文中。 因此,它還將檢查同一實體(相同 ID)的另一個已附加實例,並通過將所有值從新傳遞的實例復制到另一個附加實例來保持該實體的另一個實例同步:
https://github.com/hibernate/hibernate-orm/blob/734b80c531bdb2a9bb33971cd57f51fce662e758/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java#L346
(這是有道理的,因為否則您最終會在附加實體上獲得不同的值,並且您無法決定在事務結束時將哪些值保留到數據庫中。)

為了防止您的dbDomain實例被更新,您可以在調用save(updated)之前手動將其從持久性上下文中分離:

T dbDomain = get(updated.getId());
entityManager.detach(dbDomain); // <--
T updatedData = repository.save(updated);    

或者,您也可以深度復制相關的dbDomain屬性值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM