当前位置: 首页 > 知识库问答 >
问题:

Spring数据JPA审核在Spring boot项目中的更新期间不起作用

顾靖
2023-03-14

我正在构建一个Spring启动应用程序。我对这项技术还很陌生。我已经看到了许多关于如何启用审计的示例。我似乎已经遵循了所需的配置和设置。但是在标记lastModifiedBy的“更新”操作期间,审计不起作用

以下是我在项目中的代码

实体-我ssue.java

@Entity
@Table(name="Issue")
@EntityListeners(AuditingEntityListener.class)
@Scope("session")
public class Issue extends Auditable<String> {

    @Id
    @GenericGenerator(name = "sequence_issue_id", strategy = "com.app.mycompany.AgileCenterServices.util.IssueIdGenerator",
                      parameters = @Parameter(name = "ProjectKey", value = "PeopleCenter" ))
    @GeneratedValue(generator = "sequence_issue_id")
    @Column(unique = true)
    private String id;

    private String issueType;

    public Issue() {}

    /* getters and setters */
}

一个uditable.java

import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;

import java.util.Date;

import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import static javax.persistence.TemporalType.TIMESTAMP;

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
abstract public class Auditable<U> {

    @CreatedBy
    protected U createdBy;

    @CreatedDate
    @Temporal(TIMESTAMP)
    protected Date createdDate;

    @LastModifiedBy
    protected U lastModifiedBy;

    @LastModifiedDate
    @Temporal(TIMESTAMP)
    protected Date lastModifiedDate;

    public U getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(U createdBy) {
        this.createdBy = createdBy;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public U getLastModifiedBy() {
        return lastModifiedBy;
    }

    public void setLastModifiedBy(U lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }

    public Date getLastModifiedDate() {
        return lastModifiedDate;
    }

    public void setLastModifiedDate(Date lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }

}

审核配置。JAVA

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;


@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class AuditConfiguration {

    @Bean
    public AuditorAware<String> auditorProvider() {
        return new AuditorAwareImpl();
    }

}

AuditAwareImpl。JAVA

import javax.persistence.EntityManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.context.SecurityContextHolder;

import org.springframework.security.core.userdetails.User;


public class AuditorAwareImpl implements AuditorAware<String> {

    public static final Logger logger = LoggerFactory.getLogger(AuditorAwareImpl.class);

    @Autowired
    EntityManager entityManager;

    @Override
    public String getCurrentAuditor() {

        logger.info("Inside getCurrentAuditor() API");

        String user = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();

        logger.info("Logged in user information ::: " + user); // Not getting called during update operation

        return user;

    }

}

IssueController。JAVA

@CrossOrigin
    @RequestMapping(value = "/updateOne", method = RequestMethod.PUT)
    public Issue updateIssue(@RequestParam String issueId, @RequestBody Map<String, String> customUpdateQuery) throws Exception {

        logger.info("Inside updateIssue() API :: Updating Issue ::: " + issueId);

        if(issueId == null) {
            logger.info("Issue Id information was not passed. Raising an error");
            throw new Exception("Mandatory Input parameter (IssueId) not passed to updateIssue() API");
        }

        logger.info("updateIssue() :: Logging input parameters passed for updated!");

        if(customUpdateQuery != null) {
            for(String key : customUpdateQuery.keySet()) {
                logger.info( " Key ::: (" + key + ") ==> value ::: (" + customUpdateQuery.get(key) + ")");
            }
        }

        int recordsUpdated = 0;

        try {
            recordsUpdated = issueService.updateIssuebyIssueId(issueId, customUpdateQuery);

        } catch(NoResultException e) {
            System.out.println("No records found");
            e.printStackTrace();
            throw new NoResultException();
        } catch(Exception e) {
            System.out.println("Exception encountered");
            e.printStackTrace();
            throw new Exception("Exception encountered in update");
        }

        logger.info("Leaving updateEpic() API");

        Issue updatedIssue = null;

        if(recordsUpdated > 0 ) {
            updatedIssue =  getIssueById(issueId);
        }

        return updatedIssue;

    }

发行服务mpl.java

@Override
    @Transactional
    public int updateIssuebyIssueId(String issueId, Map<String, String> customUpdateQuery)
            throws NoResultException, Exception {

        logger.info(" Inside updateIssuebyIssueId() API in IssueServiceImpl ::: " + issueId);

        int columnsToUpdate = 0;

        StringBuilder updateSqlQuery = new StringBuilder("update issue i set ");

        for(String key : customUpdateQuery.keySet()) {

            String column = key;

            if(key != null && key.equalsIgnoreCase("issueType")) {
                column = "issue_type";
            }

            if(key != null && key.equalsIgnoreCase("dueDate")) {
                column = "due_date";
            }

            if(key != null && key.equalsIgnoreCase("startDate")) {
                column = "start_date";
            }

            if(key != null && key.equalsIgnoreCase("assignedToUser")) {
                column = "assigned_to_user";
            }

            if(key != null && key.equalsIgnoreCase("requestedBy")) {
                column = "requested_by";
            }

            if(columnsToUpdate == 0) {

                updateSqlQuery = updateSqlQuery.append("i." + column).append(" = ?");
            } 
            else {

                updateSqlQuery = updateSqlQuery.append(", ");

                updateSqlQuery = updateSqlQuery.append("i." + column).append(" = ?");
            }

            columnsToUpdate++;          
        }

        updateSqlQuery.append(" where i.id = ?");

        logger.info("updateIssuebyIssueId() :: Update Query :: " + updateSqlQuery);

        Query query = entityManager.createNativeQuery(updateSqlQuery.toString());

        int index = 1;
        int recordsUpdated = 0;

        for(String key: customUpdateQuery.keySet()) {

            query.setParameter(index, customUpdateQuery.get(key));
            index++;
        }

        query.setParameter(index, issueId);

        logger.info("updateIssuebyIssueId() :: Final Update Query with values :: " + updateSqlQuery);

        try {

            entityManager.joinTransaction();

            recordsUpdated = query.executeUpdate();

        }catch(NoResultException e) {
            System.out.println("No records found");
            e.printStackTrace();
            throw new NoResultException();
        }catch (Exception e) {
            System.out.println("Exception encountered");
            e.printStackTrace();
            throw new Exception("Exception encountered");
        }

        return recordsUpdated;

    }

我可以看到,在创建记录时,“createdBy”、“createdDate”、“lastModifiedBy”、“lastModifiedDate”都是按要求标记的。

不确定为什么在更新操作期间未调用它?

我错过了什么。

共有1个答案

岳泉
2023-03-14

Spring数据JPA审核在更新期间不起作用的原因是您在更新期间没有使用Spring数据JPA。

您可以手动创建并执行一个查询,直接调用EntityManager。

如果要使用Data JPA功能,请先使用Data JPA:

Issue issue = issueRepository.findById(id);

// modify properties

issueRepository.save(issue);

或者,您可以使用Spring Data REST,它为您的存储库自动生成所有RESTendpoint,并开箱即用地处理GET/POST/PUT/PATCH。

 类似资料:
  • 我正在阅读“ProSpring3”一书,并尝试在我的项目中使用Spring Data JPA功能。我在这里发布相关文件。 src/main/java/foo/bar/domain/ContactAudit。java语言: src/main/java/foo/bar/repository/ContactAuditRepository.java : src/main/java/foo/bar/serv

  • 我正在使用Spring Mongo审计和@CreatedDate@CreatedBy不工作,但@LastModifiedDate和@LastModifiedBy工作正常。 我在配置类上添加了@EnableMongoAudting,并定义了AuditAware。 审核类别为: 当我保存文档时,它在createdOn和createdBy中都设置为null,但在modifiedOn和modifiedBy

  • 问题内容: 我有Spring MVC + JPA应用程序。 我的应用程序中有几个实体在不断变化。我希望能够审核此更改。我发现有一个注释可以跟踪对某些字段或整个实体的更改。我想知道是否有任何方法可以配置此跟踪选项- 我希望能够跟踪更改的内容以及更改的人。还可以对SQL 1个表中的多个实体进行更改吗?还可以跟踪- 实体字段的变化吗? 谢谢 问题答案: 是的,您可以跟踪所做的更改,更新的用户和时间戳。

  • 前一段时间,我的查询对于单行更新很有效。现在我必须修改这个查询来更新多行。查询是本机的,使用postgresql和postgis。 老问题是: 在新的查询中,我在中添加了一些参数,如下所述: 但可悲的是,这种改变没有任何效果。(如果我午餐从postgresql查询它运行完美)。我该怎么解决? 编辑:我添加了查询,但它适用于postgresql。唯一的区别是旧版本:目标是一行,新的以多行为目标。id

  • 我正在使用spring数据的审计能力,并且有一个类似于这样的类: 现在,我相信我已经很好地配置了审计,因为我可以看到在更新域对象时,createdBy、createdDate、lastModifiedBy和lastModifiedDate都得到了正确的值。 但是,我的问题是,当我更新一个对象时,我会丢失createdBy和createddate的值。所以,当我第一次创建对象时,我有所有四个值,但是

  • 在一个Spring Boot项目中,我使用像@CreatedDate这样的注释来保存关于相应文档创建/更新日期的信息。ZonedDateTime在整个项目中使用,因此带注释的字段也是ZonedDateTime。为了实现Mongo的日期格式和ZonedDateTime之间的转换,使用了自定义转换器。 现在,当使用Spring Boot 1.5.x时,自定义转换器可以完美地用于可审计字段。在Sprin