#java #spring #hibernate #jpa
#java #весна #спящий режим #jpa
Вопрос:
Я создал один объект JPA следующим образом:
MyEntity выглядит следующим образом:
@Entity
@Table(name = "my_table")
public class MyEntity extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "custom-uuid")
@GenericGenerator(name = "custom-uuid",
strategy = "generator.CustomUUIDGenerator")
private String id;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
AbstractAuditingEntity выглядит следующим образом:
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
@CreatedBy
@Column(name = "created_by", nullable = false, length = 50, updatable = false)
@JsonIgnore
private String createdBy;
@CreatedDate
@Column(name = "created_date", updatable = false)
@JsonIgnore
private Instant createdDate = Instant.now();
@LastModifiedBy
@Column(name = "last_modified_by", length = 50)
@JsonIgnore
private String lastModifiedBy;
@LastModifiedDate
@Column(name = "last_modified_date")
@JsonIgnore
private Instant lastModifiedDate = Instant.now();
Теперь я обновляю объект в БД следующим утверждением:
MyEntity savedEntity = threatCanvasRepository.save(myEntity);
Здесь, в savedEntity
объекте, lastModifiedBy
установлено значение null.
Несмотря на то, что я извлекаю то же самое из БД, я могу видеть, что lastModifiedBy установлен. Я не могу понять, чего мне здесь не хватает.
Редактировать
Самое странное, что я получаю CreatedDate и LastModifiedDate в ответе, но не CreatedBy и lastModifiedBy.
Комментарии:
1. Вы настроили
AuditingEntityListener
и внедрилиAuditorAware
?2. Да, я сделал. Самое странное, что я получаю createddate и LastModifiedDate , но не получаю CreatedBy и lastModifiedBy.
3. Можете ли вы показать нам реализацию
AuditorAware
?
Ответ №1:
Я предполагаю, что ваш сервис @Transactional
, то Repository.save()
на самом деле не сохраняет его в БД немедленно, он добавляет его к текущей транзакции для последующей обработки. @CreatedDate
, @CreatedBy
, @LastModifiedBy
и @LastModifiedDate
аннотации обрабатываются, когда транзакция фактически выполняется JPA (я предполагаю, что спящий режим). Итак, вам необходимо выполнить выборку из другой службы после совершения текущей транзакции. Но обычно вам это просто не нужно. Просто поверьте, что они находятся в БД.
Комментарии:
1. Да, @Viktar вы абсолютно правы. Да, на самом деле я хотел поля в ответе. Но я думаю, что нет способа получить эти поля в одном потоке.
Ответ №2:
Вы включили аудит JPA в своем приложении?
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
public class JpaAuditingConfiguration {
@Bean
public AuditorAware<String> auditorProvider() {
/*
if you are using spring security, you can get the currently logged username with following code segment.
SecurityContextHolder.getContext().getAuthentication().getName()
*/
return new UsernameAuditorAware();
}
}
Это необходимо для работы аннотации @LastModifiedBy.