Spring JPA Hibernate Auto Populate Audit Fields (Create ID / Timestamp etc)

George :

I have an entity class that I would like to audit:

@Data    // Lombok for getters/setters
@Entity
public class EventEntity {
  @Id
  private Long id;
  @CreatedBy
  private String createdId;
  private LocalDateTime creationTimestamp;  // @CreatedDate or @CreationTimestamp
  @LastModifiedBy
  private String modifiedId;
  private LocalDateTime lastModifiedTimestamp; // @LastModifiedDate or @UpdateTimestamp
  // other fields
}

And I have a JpaRepository for database operations:

public interface EventRepository extends JpaRepository<EventEntity, Long> {
  // Empty
}

There are these annotations and I'm not sure which date annotation I should be using:

org.springframework.data.annotation.CreatedBy
org.springframework.data.annotation.CreatedDate
org.hibernate.annotations.CreationTimestamp

org.springframework.data.annotation.LastModifiedBy
org.springframework.data.annotation.LastModifiedDate
org.hibernate.annotations.UpdateTimestamp

For The @CreatedBy / @LastModifiedBy fields I've implemented org.springframework.data.domain.AuditorAware as per documentation that just returns a constant:

@Component("auditor")
public class CustomAuditorAware implements AuditorAware<String> {

@Override
  public Optional<String> getCurrentAuditor() {
     return Optional.of("ID");
  }
}

And I've enabled JPA Auditing:

@Configuration
@EnableJpaAuditing("auditor")
public class AppConfig {
}

Here how I've tried persisting to the DB:

EventEntity eventEntity = eventRepository.findById("ID") // returns Optional
    .orElse(new EventEntity());
eventEntity.setSomeField("New Value");
eventRepository.save(eventEntity);

(Please correct me on the hibernate entity states if I am wrong below)

Situation 1: EventEntity is new

The no args constructor is called and now the eventEntity is in transient state. The save() method executes a select query followed by an update query, which will error out with this message:

java.sql.BatchUpdateException: Cannot insert the value NULL into column 'CREATED_ID'

Situation 2: EventEntity exists already

The eventEntity is now in the detached state. The audit fields are already populated. The save() method executes a update query, but none of the audit fields are changed.

Ideal Solution

I don't really care about any of the existing data fields, I just want to update if it exists already. So ideally I won't call the findById() method. I'll create an EventEntity in the transient state and it will retain the createdId and creationTimestamp data. So almost like above:

EventEntity eventEntity = new EventEntity();
eventEntity.setSomeField("New Value");
eventRepository.save(eventEntity);

My Problem

None of the auditing fields are working as I expect it to. How do I get it working?

Which audit date annotations should I be using? The one from Spring JPA or from hibernate? I've tried both sets with no luck. What's the difference between each?

Versions:

  • Spring Boot 2.1
  • Hibernate 5.3.10.final
belbix :

Just add the following annotation in the entity class

@EntityListeners(AuditingEntityListener.class)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=153588&siteId=1