Überwachungsfelder geben Null zurück, nachdem „entity(save())“ in der mehrinstanzenfähigen Spring Data JPA-App aktualisiJava

Java-Forum
Guest
 Überwachungsfelder geben Null zurück, nachdem „entity(save())“ in der mehrinstanzenfähigen Spring Data JPA-App aktualisi

Post by Guest »

Ich arbeite mit einer mandantenfähigen Spring Boot-App unter Verwendung von Spring Data JPA und Hibernate. Meine Entität verfügt über Überwachungsfelder (@CreatedBy, @CreatedDate, @LastModifiedBy, @LastModifiedDate), die über @EnableJpaAuditing ausgefüllt wurden, und sie werden korrekt in der Datenbank gespeichert.
Nach dem Aufruf von save() Um die Entität zusammenzuführen, werden die Überwachungsfelder der zurückgegebenen Entität auf Null gesetzt, auch wenn sie korrekt in der Datenbank gespeichert sind. Wenn ich „entityManager.refresh(object)“ aufrufe, werden die Felder korrekt ausgefüllt, aber ich möchte die Datenbank nicht erneut abfragen.
Hier ist mein Code:
Modelle:

Code: Select all

@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;
}

Code: Select all

@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:

Code: Select all

@Repository
public interface SystemConfigurationRepository extends JpaRepository {

Optional findByCode(SystemConfigurationTypeEnum code);

void deleteByCode(SystemConfigurationTypeEnum code);

boolean existsByCode(SystemConfigurationTypeEnum code);
}
PersistenceConfig:

Code: Select all

@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;
}
Dienstmethode:

Code: Select all

    @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 GenericException(SERVICE_TYPE_NOT_FOUND, code));

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

return mapper.toDTO(systemConfiguration);
}
Mapper (Impl legt alle Felder fest):

Code: Select all

@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);
}
Aktuelle Ausgabe:

Code: Select all

{
"id": "fdc59f03-27c7-436d-8022-8e28786639d0",
"createdBy": null,
"createdDate": null,
"lastModifiedBy": null,
"lastModifiedDate": null,
"code": "data",
"description": "data",
"value": "data",
"active": true,
"version": 4
}
Erwartete Ausgabe:

Code: Select all

{
"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
}
Sichergestellt, dass @EnableJpaAuditing konfiguriert ist. SaveAndFlush() verwendet, das @LastModifiedBy und @LastModifiedDate füllt, aber @CreatedBy und @CreatedDate sind immer noch null. Die Überwachungsfelder werden korrekt beibehalten, aber nach save() nicht in der Entität zurückgegeben.
Ich möchte den Aufruf von „entityManager.refresh()“ vermeiden und alle Überwachungsfelder ohne eine zusätzliche Datenbankabfrage füllen lassen. Wie kann ich das erreichen?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post