В настоящее время у меня есть сущность, как показано ниже:
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long productId;
private String productImage;
private String productTitle;
private String productDescription;
private Integer productPrice;
private Date createdAt;
private Date updatedAt;
После создания этого объекта значение createdAt и updatedAt показывает null в базе данных, и мне было интересно, как я могу реализовать код, чтобы createdAt и updateAt автоматически вставлялись?
Мой метод публикации следующий:
@PostMapping("/products")
public ProductResponse createProduct(@Validated @RequestBody ProductForm productForm) {
Product product = productForm.asProduct();
Product createdProduct = productRepository.save(product);
return new ProductResponse(createdProduct, "Product created");
}




JPA
Нет ничего более удобного, чем аннотирование поля Timestamp напрямую, но вы можете использовать аннотации @PrePersist, @PreUpdate и с небольшими усилиями достичь тех же результатов.
Спящий режим
@CreationTimestamp - Документация@UpdateTimestamp - ДокументацияSpring Data JPA
@CreatedDate - Документация@LastModifiedDate - ДокументацияВы можете создать BaseEntity. Каждая сущность расширяет BaseEntity. В сущности Base он установит время автоматически.
@Data
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity implements Serializable {
@Id
@Column(name = "Id")
private String id;
@Column(name = "deleted", columnDefinition = "Bit(1) default false")
private boolean deleted = false;
@Column(name = "DataChange_CreatedBy", nullable = false)
private String dataChangeCreatedBy;
@Column(name = "DataChange_CreatedTime", nullable = false)
private Date dataChangeCreatedTime;
@Column(name = "DataChange_LastModifiedBy")
private String dataChangeLastModifiedBy;
@Column(name = "DataChange_LastTime")
private Date dataChangeLastModifiedTime;
@PrePersist
protected void prePersist() {
if (this.dataChangeCreatedTime == null) dataChangeCreatedTime = new Date();
if (this.dataChangeLastModifiedTime == null) dataChangeLastModifiedTime = new Date();
}
@PreUpdate
protected void preUpdate() {
this.dataChangeLastModifiedTime = new Date();
}
@PreRemove
protected void preRemove() {
this.dataChangeLastModifiedTime = new Date();
}
}
Благодаря сочетанию ответов @dimitrisli и @buddha получается что-то довольно чистое.
@Data
@MappedSuperclass
public abstract class BaseEntity {
@Column(updatable = false)
@CreationTimestamp
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
}
И теперь вы, вся ваша сущность, можете расширить этот класс вот так
@Data
@Entity
@EqualsAndHashCode(callSuper = true)
public class User extends BaseEntity {
@Id
@GeneratedValue
public UUID id;
public String userName;
public String email;
public String firstName;
public String lastName;
}
Обратите внимание, что вам могут не понадобиться аннотации @Данные и @EqualsAndHashCodeannotation от lombok, поскольку он генерирует геттер / сеттер
Расширьте следующий абстрактный класс в своей сущности:
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class DateAudit implements Serializable {
@CreatedDate
@Column(name = "created_at", nullable = false, updatable = false)
private Date createdAt;
@LastModifiedDate
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}
Не забудьте включить функцию аудита JPA с помощью @EnableJpaAuditing
Прочтите это: https://docs.spring.io/spring-data/jpa/docs/1.7.0.DATAJPA-580-SNAPSHOT/reference/html/auditing.html
Намного лучшее и эффективное решение по существу и простое. Оценил !!
Будет ли это устанавливать время системы или время системы базы данных? У меня проблема в том, что иногда системное время может быть неправильным и не контролировать его, в то время как системное время db правильное (и, что более важно, уникальное)