Поля аудита возвращают значение null после обновления объекта (save()) в мультитенантном приложении Spring Data JPA.JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Поля аудита возвращают значение null после обновления объекта (save()) в мультитенантном приложении Spring Data JPA.

Сообщение Anonymous »

Я работаю с мультитенантным приложением Spring Boot, используя Spring Data JPA и Hibernate. У моей сущности есть поля аудита (@CreatedBy, @CreatedDate, @LastModifiedBy, @LastModifiedDate), заполненные с помощью @EnableJpaAuditing, и они правильно сохраняются в базе данных.
Однако после вызова save() для объединения сущности возвращаемая сущность имеет поля аудита, установленные в значение null, даже если они правильно сохраняются в базе данных. Когда я вызываюentityManager.refresh(object), поля заполняются правильно, но я не хочу снова запрашивать базу данных.
Вот мой код:
Модели:

Код: Выделить всё

@Getter
@Setter
@MappedSuperclass
@RequiredArgsConstructor
@Audited(targetAuditMode = NOT_AUDITED)
@EntityListeners(AuditingEntityListener.class)
public class AbstractEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private UUID id;

@Column(updatable = false)
@CreatedBy
private String createdBy;

@Column(updatable = false)
@CreatedDate
private LocalDateTime createdDate;

@Column
@LastModifiedBy
private String lastModifiedBy;

@Column
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}

Код: Выделить всё

@Entity
@Getter
@Setter
@Audited
public class SystemConfiguration extends AbstractEntity {

@Enumerated(EnumType.STRING)
private SystemConfigurationTypeEnum code;

@Column
private String description;

@Column
private String value;

@Column(columnDefinition = "boolean default true")
private boolean active = true;

@Version
@NotAudited
private Integer version;
}
Репозиторий:

Код: Выделить всё

@Repository
public interface SystemConfigurationRepository extends JpaRepository {

Optional findByCode(SystemConfigurationTypeEnum code);

void deleteByCode(SystemConfigurationTypeEnum code);

boolean existsByCode(SystemConfigurationTypeEnum code);
}
PersistenceConfig:

Код: Выделить всё

@Configuration
@EnableJpaRepositories(
basePackages = {"${multitenancy.tenant.repository.packages}"},
entityManagerFactoryRef = "tenantEntityManagerFactory",
transactionManagerRef = "tenantTransactionManager"
)
@EnableConfigurationProperties(JpaProperties.class)
public class TenantPersistenceConfig {

@Autowired
private ConfigurableListableBeanFactory beanFactory;

@Autowired
private JpaProperties jpaProperties;

@Value("${multitenancy.tenant.entityManager.packages}")
private String entityPackages;

@Bean
@Primary
public LocalContainerEntityManagerFactoryBean tenantEntityManagerFactory(
@Qualifier("dynamicDataSourceBasedMultiTenantConnectionProvider") MultiTenantConnectionProvider connectionProvider,
@Qualifier("currentTenantIdentifierResolver") CurrentTenantIdentifierResolver tenantResolver) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPersistenceUnitName("tenant-persistence-unit");
em.setPackagesToScan(entityPackages);

JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);

Map properties = new HashMap(this.jpaProperties.getProperties());
properties.put(BEAN_CONTAINER, new SpringBeanContainer(this.beanFactory));
properties.put(MULTI_TENANT_CONNECTION_PROVIDER, connectionProvider);
properties.put(MULTI_TENANT_IDENTIFIER_RESOLVER, tenantResolver);
properties.put("hibernate.physical_naming_strategy", "system_configurations_service.multitenancy.MyPhysicalNamingStrategy");
em.setJpaPropertyMap(properties);

return em;
}

@Bean
@Primary
public JpaTransactionManager tenantTransactionManager(
@Qualifier("tenantEntityManagerFactory") EntityManagerFactory emf) {
JpaTransactionManager tenantTransactionManager = new JpaTransactionManager();
tenantTransactionManager.setEntityManagerFactory(emf);
return tenantTransactionManager;
}
Метод обслуживания:

Код: Выделить всё

    @Override
public SystemConfigurationDTO update(SystemConfigurationTypeEnum code, SystemConfigurationDTO systemConfigurationDTO) throws Exception {
log.debug("Request to update System Configuration by code: {}", code);

repository.findByCode(code).orElseThrow(() ->  new PortalGenericException(SERVICE_TYPE_NOT_FOUND, code));

SystemConfiguration systemConfiguration = repository.save(mapper.toEntity(systemConfigurationDTO));

return mapper.toDTO(systemConfiguration);
}
Mapper (осуществляется установка всех полей):

Код: Выделить всё

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface SystemConfigurationMapper {

SystemConfiguration toEntity(SystemConfigurationDTO dto);

SystemConfiguration toEntity(SystemConfigurationPatchDTO dto);

SystemConfigurationDTO toDTO(SystemConfiguration entity);

List toDTO(List entityList);
}
Вывод на данный момент:

Код: Выделить всё

{
"id": "fdc59f03-27c7-436d-8022-8e28786639d0",
"createdBy": null,
"createdDate": null,
"lastModifiedBy": null,
"lastModifiedDate": null,
"code": "data",
"description": "data",
"value": "data",
"active": true,
"version": 4
}
Ожидаемый результат:

Код: Выделить всё

{
"id": "fdc59f03-27c7-436d-8022-8e28786639d0",
"createdBy": "system",
"createdDate": "2025-01-16 09:36:39",
"lastModifiedBy": "anonymousUser",
"lastModifiedDate": "2025-01-17 15:12:45",
"code": "data",
"description": "data",
"value": "data",
"active": true,
"version": 4
}
Гарантированно настроен @EnableJpaAuditing. Используется saveAndFlush(), который заполняет @LastModifiedBy и @LastModifiedDate, но @CreatedBy и @CreatedDate по-прежнему имеют значение NULL. Поля аудита сохраняются правильно, но не возвращаются в объекте после сохранения().
Я хочу избежать вызоваentityManager.refresh() и заполнить все поля аудита без дополнительного запроса к базе данных. Как мне этого добиться?

Подробнее здесь: https://stackoverflow.com/questions/793 ... ant-spring
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Поля аудита возвращают значение null после обновления объекта (save()) в мультитенантном приложении Spring Data JPA.
    Anonymous » » в форуме JAVA
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous
  • Вставка нежелательного аудита и неожиданного аудита в Hibernate
    Anonymous » » в форуме JAVA
    0 Ответы
    24 Просмотры
    Последнее сообщение Anonymous
  • Вставка нежелательного аудита и неожиданного аудита в Hibernate
    Anonymous » » в форуме JAVA
    0 Ответы
    28 Просмотры
    Последнее сообщение Anonymous
  • Android Monhofit Post Type Data Data Wations Data Null Null
    Anonymous » » в форуме Android
    0 Ответы
    46 Просмотры
    Последнее сообщение Anonymous
  • Android Monhofit Post Type Data Data Wations Data Null Null
    Anonymous » » в форуме Android
    0 Ответы
    38 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»