Я работаю над созданием весеннего загрузочного приложения. Я совсем новичок в этой технологии. Я видел множество примеров того, как включить аудит. Кажется, я выполнил необходимые конфигурации и настройки. Но аудит не работает во время операции «Обновление», чтобы пометить столбцы 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» помечаются как требуется.
Не знаете, почему он не вызывается во время операции обновления?
Что мне здесь не хватает.




Причина, по которой аудит 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 из коробки.
Где вы делаете обновление? Мне непонятно, какая у вас проблема.