【问题标题】:Does setter generates hibernate query for Entity class automaticallysetter 是否自动为实体类生成休眠查询
【发布时间】:2026-01-13 03:00:02
【问题描述】:

我在 Hibernate JPA spring boot 应用程序中有一个使用 lombok 的实体类。在分析代码时,我找不到任何save() 代码。 setter 是否自动生成 Hibernate 查询并将它们保存到 DB。

@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString(callSuper = true)
@Entity
@Table(name = "operation", schema = "ssp")
public class Operation extends CommonEntity{
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ToString.Exclude
    @ManyToOne
    @JoinColumn(name = "router_ref_id")
    private Router router;

    @ToString.Exclude
    @OneToMany(mappedBy = "operation", cascade = CascadeType.ALL)
    @OrderBy("sequence")
    private List<OperationQr> qrList;

    @ToString.Exclude
    @OneToMany(mappedBy = "operation", cascade = CascadeType.ALL)
    private Set<OperationDependency> operationDependencies;

    @ToString.Exclude
    @OneToMany(mappedBy = "operation", cascade = CascadeType.ALL)
    @OrderBy("sequence")
    private Set<OperationDocument> opnDocumentList;

    @ToString.Exclude
    @OneToOne
    @JoinColumn(name = "operation_interface")
    private OperationInterface operationInterface;

    @Column(name = "router_operation_id")
    private Integer routerOperationId;

    @Column(name = "tenant_id")
    private String tenantId;

    @Column(name = "external_system_sequence")
    private String externalSystemSequence;

保存Operation及其部分的代码是:

private Operation saveDetails(OperationDetailsViewModel newOperationData, String sso, Router router, Operation operation) {
    copyProperties(newOperationData, operation);
    
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();

    Optional<XRefWorkcenterRequirementProfile> requirementProfile = workCenterService.getRequirementProfileFor( router, newOperationData.getWorkCenter().getId() );
    
    operation.setRequrementProfile(requirementProfile.isPresent() ? requirementProfile.get().getProfileId() : null);
    
    if (isOperationInterfaceChanged(operation.getOperationInterface(), newOperationData.getOperationInterface())) {
        OperationInterface newOperationInterface = operationInterfaceService.getOperationInterface(
                router.getEnterprise(), router.getBusinessUnit(), router.getPlant(), newOperationData.getOperationInterface().getId());
        operation.setOperationInterface(newOperationInterface);
    qualityResultService.removeOldQr(operation);
    List<OperationQr> qrList = qualityResultService.createQrList(sso, operation, newOperationData.getGlobalQr());
    qrList.addAll(qualityResultService.createQrList(sso, operation, newOperationData.getLocalQr()));
    operation.setQrList(qrList);

    Set<OperationDependency> operationDependencies = operationDependenciesService.createDependencies( sso, operation, newOperationData.getDependencies() );
    operationDependencySetValidator.validateDependencySet( operationDependencies );
    operationDependenciesService.removeOldDependencies( operation );
    operation.setOperationDependencies( operationDependencies );

    documentService.removeOldOperationDocuments(operation);
    operation.setOpnDocumentList(documentService.createDocuments(sso, operation, newOperationData.getDocuments()));

    purchaseDetailService.updatePurchaseDetail(sso, operation, newOperationData.getPurchaseDetails());
    addCustomFields( sso, operation, newOperationData ) ;

    OperationUtils.setEntityUpdateData( operation, sso );
    
    stopWatch.stop();
    LOGGER.info("..........SaveOperationDetails.......... Total time = " + stopWatch.getTotalTimeMillis() + " ms");

    return operation;
}

saveDetails() 被包裹在另一个方法中,即@Transactional

 @Transactional
    public Operation addOperation( OperationDetailsViewModel newOperationData, int indexToAdd, String sso, String changeRequestNumber ) {
        Router router = getEditableRouter( newOperationData.getRouterId(), sso, changeRequestNumber );
        Operation operation = prepareNewOperation(sso, router);
        OperationUtils.addOperationToIndexWithResequencing( router.getOperationsList(), operation, indexToAdd );
        return saveDetails(newOperationData, sso, router, operation);
    }




private Operation mergeOperation(OperationDetailsViewModel operationDetailsViewModel, int i, String sso,
    String changeRequestNumber, Router router, RouterLock routerLock) {
    Operation operation;

    if(operationDetailsViewModel.getId() == null) {
        operation = saveOperationDetailsService
            .addOperation(operationDetailsViewModel, i, sso, changeRequestNumber);
    }
    else {
        operation = saveOperationDetailsService
            .updateOperation(operationDetailsViewModel, sso, changeRequestNumber, router, routerLock);
    }

    return operation;
}




  public static void addOperationToIndexWithResequencing(List<Operation> operations,
      Operation newOperationWithoutSequence, int indexToAdd) {
    operations.sort(Comparator.comparing(Operation::getSequence));

    if (indexToAdd < operations.size()) {
      operations.add(indexToAdd, newOperationWithoutSequence);
    } else {
      operations.add(newOperationWithoutSequence);
    }

    resequenceOperations(operations);
  }

【问题讨论】:

  • 你的意思是save()方法是用来持久化表中数据的吗?
  • 否 - lombok 不会生成任何休眠调用。据推测,saveDetails(...) 被包装在事务中,对现有实体的更新由事务管理器(不是 lombok)处理。
  • 是的..我找不到任何相关的代码。
  • addOperation() 调用的@Transactional 是否会生成这些查询?
  • prepareNewOperation 是否有任何代码从存储库加载操作实体?

标签: java spring hibernate java-8 spring-data-jpa


【解决方案1】:

如果 Operation 实体是 托管 实体(它是从某个 jpa 存储库中检索的,例如 findOne 等),则不需要显式保存或持久调用。它会在事务结束时自动保存。

我相信,您一定是在此处某处调用存储库 -

Operation operation = prepareNewOperation(sso, router);
OperationUtils.addOperationToIndexWithResequencing( router.getOperationsList(), operation, indexToAdd );

类似的答案在这里 - https://*.com/a/46708295/11244881

【讨论】:

  • 我给了两个代码..它仍然在这些方法中设置
  • 但我同意那篇文章中提到的观点..这个操作是通过 findone() 调用拉出来的,所有的设置器都在那之后完成
【解决方案2】:

"setter 是否自动生成 Hibernate 查询并将它们保存到 DB。- 否

基本上save() 存在于 CrudRepository 上。 JpaRepository 扩展了 CrudRepository。因此它继承了 CrudRepository 的所有方法。检查文档链接。

https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html

https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html

【讨论】: