Аудит данных Spring JPA не работает во время обновления в проекте весенней загрузки

Я работаю над созданием весеннего загрузочного приложения. Я совсем новичок в этой технологии. Я видел множество примеров того, как включить аудит. Кажется, я выполнил необходимые конфигурации и настройки. Но аудит не работает во время операции «Обновление», чтобы пометить столбцы lastModifiedBy и lastModifiedDate.

Ниже приведен код, который у меня есть в моем проекте.

Сущность - Выпуск.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;
    }

}

АудитКонфигурация.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» помечаются как требуется.

Не знаете, почему он не вызывается во время операции обновления?

Что мне здесь не хватает.

Где вы делаете обновление? Мне непонятно, какая у вас проблема.

Dherik 01.03.2019 17:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
7 365
1

Ответы 1

Причина, по которой аудит 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 из коробки.

Другие вопросы по теме