JPA Refactoring (2) (#2108)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -86,7 +86,8 @@ public final class JpaManagementHelper {
|
||||
|
||||
public static <J extends AbstractJpaBaseEntity> J touch(final EntityManager entityManager,
|
||||
final CrudRepository<J, ?> repository, final J entity) {
|
||||
// merge base entity so optLockRevision gets updated and auditing log written because modifying e.g. metadata is modifying the base
|
||||
// merge base entity so optLockRevision gets updated and audit
|
||||
// log written because modifying e.g. metadata is modifying the base
|
||||
// entity itself for auditing purposes.
|
||||
final J result = entityManager.merge(entity);
|
||||
result.setLastModifiedAt(0L);
|
||||
|
||||
@@ -42,9 +42,8 @@ public class ExceptionMappingAspectHandler implements Ordered {
|
||||
private static final Map<String, String> EXCEPTION_MAPPING = new HashMap<>(4);
|
||||
|
||||
/**
|
||||
* this is required to enable a certain order of exception and to select the
|
||||
* most specific mappable exception according to the type hierarchy of the
|
||||
* exception.
|
||||
* this is required to enable a certain order of exception and to select the most specific mappable exception according to the type
|
||||
* hierarchy of the exception.
|
||||
*/
|
||||
private static final List<Class<?>> MAPPED_EXCEPTION_ORDER = new ArrayList<>(4);
|
||||
|
||||
@@ -72,22 +71,18 @@ public class ExceptionMappingAspectHandler implements Ordered {
|
||||
// It is a AspectJ proxy which deals with exceptions.
|
||||
@SuppressWarnings({ "squid:S00112", "squid:S1162" })
|
||||
public void catchAndWrapJpaExceptionsService(final Exception ex) throws Throwable {
|
||||
|
||||
// Workaround for EclipseLink merge where it does not throw ConstraintViolationException directly in case of
|
||||
// existing entity update
|
||||
// Workaround for EclipseLink merge where it does not throw ConstraintViolationException directly in case of existing entity update
|
||||
if (ex instanceof TransactionSystemException) {
|
||||
throw replaceWithCauseIfConstraintViolationException((TransactionSystemException) ex);
|
||||
}
|
||||
|
||||
for (final Class<?> mappedEx : MAPPED_EXCEPTION_ORDER) {
|
||||
|
||||
if (!mappedEx.isAssignableFrom(ex.getClass())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (EXCEPTION_MAPPING.containsKey(mappedEx.getName())) {
|
||||
throw (Exception) Class.forName(EXCEPTION_MAPPING.get(mappedEx.getName()))
|
||||
.getConstructor(Throwable.class).newInstance(ex);
|
||||
throw (Exception) Class.forName(EXCEPTION_MAPPING.get(mappedEx.getName())).getConstructor(Throwable.class).newInstance(ex);
|
||||
}
|
||||
|
||||
log.error("there is no mapping configured for exception class {}", mappedEx.getName());
|
||||
|
||||
@@ -51,7 +51,8 @@ public class JpaDistributionSetCreate extends AbstractDistributionSetUpdateCreat
|
||||
|
||||
@Override
|
||||
public JpaDistributionSet build() {
|
||||
return new JpaDistributionSet(name, version, description,
|
||||
return new JpaDistributionSet(
|
||||
name, version, description,
|
||||
Optional.ofNullable(type).map(this::findDistributionSetTypeWithExceptionIfNotFound).orElse(null),
|
||||
findSoftwareModuleWithExceptionIfNotFound(modules),
|
||||
Optional.ofNullable(requiredMigrationStep).orElse(Boolean.FALSE));
|
||||
|
||||
@@ -25,8 +25,7 @@ import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* {@link JpaTransactionManager} that sets the
|
||||
* {@link TenantAware#getCurrentTenant()} in the eclipselink session. This has
|
||||
* {@link JpaTransactionManager} that sets the {@link TenantAware#getCurrentTenant()} in the eclipselink session. This has
|
||||
* to be done in eclipselink after a {@link Transaction} has been started.
|
||||
*/
|
||||
public class MultiTenantJpaTransactionManager extends JpaTransactionManager {
|
||||
|
||||
@@ -66,8 +66,7 @@ public class JpaActionManagement {
|
||||
}
|
||||
|
||||
protected List<JpaAction> findActiveActionsHavingStatus(final String controllerId, final Action.Status status) {
|
||||
return actionRepository.findAll(
|
||||
ActionSpecifications.byTargetControllerIdAndIsActiveAndStatus(controllerId, status));
|
||||
return actionRepository.findAll(ActionSpecifications.byTargetControllerIdAndIsActiveAndStatus(controllerId, status));
|
||||
}
|
||||
|
||||
protected Action addActionStatus(final JpaActionStatusCreate statusCreate) {
|
||||
|
||||
@@ -64,20 +64,15 @@ import org.springframework.validation.annotation.Validated;
|
||||
public class JpaDistributionSetTypeManagement implements DistributionSetTypeManagement {
|
||||
|
||||
private final DistributionSetTypeRepository distributionSetTypeRepository;
|
||||
|
||||
private final SoftwareModuleTypeRepository softwareModuleTypeRepository;
|
||||
|
||||
private final DistributionSetRepository distributionSetRepository;
|
||||
|
||||
private final TargetTypeRepository targetTypeRepository;
|
||||
|
||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
||||
|
||||
private final Database database;
|
||||
|
||||
private final QuotaManagement quotaManagement;
|
||||
|
||||
public JpaDistributionSetTypeManagement(final DistributionSetTypeRepository distributionSetTypeRepository,
|
||||
public JpaDistributionSetTypeManagement(
|
||||
final DistributionSetTypeRepository distributionSetTypeRepository,
|
||||
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
|
||||
final DistributionSetRepository distributionSetRepository, final TargetTypeRepository targetTypeRepository,
|
||||
final VirtualPropertyReplacer virtualPropertyReplacer, final Database database,
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.jpa.CurrentTenantCacheKeyGenerator;
|
||||
import org.eclipse.hawkbit.repository.jpa.SystemManagementCacheKeyGenerator;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
|
||||
@@ -141,16 +140,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
return currentTenantCacheKeyGenerator.currentTenantKeyGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator", cacheManager = "directCacheManager", unless = "#result == null")
|
||||
public String currentTenant() {
|
||||
return currentTenantCacheKeyGenerator.getTenantInCreation().orElseGet(() -> {
|
||||
final TenantMetaData findByTenant = tenantMetaDataRepository
|
||||
.findByTenantIgnoreCase(tenantAware.getCurrentTenant());
|
||||
return findByTenant != null ? findByTenant.getTenant() : null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
@@ -295,6 +284,12 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
.orElseThrow(() -> new EntityNotFoundException(TenantMetaData.class, tenantId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator", cacheManager = "directCacheManager", unless = "#result == null")
|
||||
public boolean tenantExists(final String tenant) {
|
||||
return tenantMetaDataRepository.findByTenantIgnoreCase(tenant) != null;
|
||||
}
|
||||
|
||||
private static boolean isPostgreSql(final JpaProperties properties) {
|
||||
return Database.POSTGRESQL == properties.getDatabase();
|
||||
}
|
||||
@@ -342,13 +337,13 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
}
|
||||
|
||||
/**
|
||||
* Creating the initial tenant meta-data in a new transaction. Due the
|
||||
* {@link MultiTenantJpaTransactionManager} is using the current tenant to
|
||||
* Creating the initial tenant meta-data in a new transaction. Due to the
|
||||
* {@link org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager} is using the current tenant to
|
||||
* set the necessary tenant discriminator to the query. This is not working
|
||||
* if we don't have a current tenant set. Due the
|
||||
* if we don't have a current tenant set. Due to the
|
||||
* {@link #createTenantMetadata(String)} is maybe called without having a
|
||||
* current tenant we need to re-open a new transaction so the
|
||||
* {@link MultiTenantJpaTransactionManager} is called again and set the
|
||||
* {@link org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager} is called again and set the
|
||||
* tenant for this transaction.
|
||||
*
|
||||
* @param tenant the tenant to be created
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
|
||||
import org.eclipse.persistence.annotations.Multitenant;
|
||||
import org.eclipse.persistence.annotations.MultitenantType;
|
||||
import org.eclipse.persistence.annotations.TenantDiscriminatorColumn;
|
||||
import org.hibernate.annotations.TenantId;
|
||||
|
||||
/**
|
||||
* Holder of the base attributes common to all tenant aware entities.
|
||||
@@ -88,11 +89,14 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn
|
||||
|
||||
/**
|
||||
* PrePersist listener method for all {@link TenantAwareBaseEntity} entities.
|
||||
*
|
||||
* // TODO - check if the tenant support should set tenant from context
|
||||
* // TODO - should we check if tenant exists in the system? Note: seems it's not good to work with db in the listener
|
||||
*/
|
||||
@PrePersist
|
||||
void prePersist() {
|
||||
// before persisting the entity check the current ID of the tenant by using the TenantAware service
|
||||
final String currentTenant = SystemManagementHolder.getInstance().currentTenant();
|
||||
final String currentTenant = TenantAwareHolder.getInstance().getTenantAware().getCurrentTenant();
|
||||
if (currentTenant == null) {
|
||||
throw new TenantNotExistException(
|
||||
String.format(
|
||||
|
||||
@@ -71,7 +71,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction> {
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@Query("UPDATE JpaAction a SET a.status = :statusToSet WHERE a.target IN :targetsIds AND a.active = :active AND a.status = :currentStatus AND a.distributionSet.requiredMigrationStep = false")
|
||||
@Query("UPDATE JpaAction a SET a.status = :statusToSet WHERE a.target.id IN :targetsIds AND a.active = :active AND a.status = :currentStatus AND a.distributionSet.requiredMigrationStep = false")
|
||||
void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("targetsIds") List<Long> targetIds,
|
||||
@Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.Optional;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity_;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaTenantAwareBaseEntity;
|
||||
@@ -65,6 +66,17 @@ public interface BaseEntityRepository<T extends AbstractJpaTenantAwareBaseEntity
|
||||
@Override
|
||||
List<T> findAll();
|
||||
|
||||
/**
|
||||
* Gets by id requiring entity to exists
|
||||
*
|
||||
* @param id the entity id
|
||||
* @return the existing entity.
|
||||
* @throws EntityNotFoundException if the entity doesn't exist
|
||||
*/
|
||||
default T getById(final Long id) {
|
||||
return findById(id).orElseThrow(() -> new EntityNotFoundException(getDomainClass(), id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides
|
||||
* {@link org.springframework.data.repository.CrudRepository#findAllById(Iterable)}
|
||||
|
||||
Reference in New Issue
Block a user