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

时间:2019-03-01 15:14:10

标签: java spring spring-boot spring-data-jpa

我正在构建一个Spring Boot应用程序。我对这项技术还很陌生。我已经看到了许多有关如何启用审核的示例。我似乎遵循了必需的配置和设置。但是,在“更新”操作中标记了lastModifiedBy和lastModifiedDate列的过程中,审计无效。

以下是我在项目中拥有的代码。

实体- Issue.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 */
}

Auditable.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;
    }

}

AuditConfiguration.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;

    }

IssueServiceImpl.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 个答案:

答案 0 :(得分:0)

在更新期间无法使用Spring Data JPA审核的原因是,在更新期间您未使用Spring Data JPA。

您手动创建并执行直接调用EntityManager的查询。

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

Issue issue = issueRepository.findById(id);

// modify properties

issueRepository.save(issue);

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