JPA Refactoring (4) (#2110)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-12-02 14:55:12 +02:00
committed by GitHub
parent a9f3d1491a
commit 6f80038619
18 changed files with 55 additions and 145 deletions

View File

@@ -61,8 +61,7 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt
@Test
@Description("Verfies that a paged result list of DS tags reflects the content on the repository side.")
@ExpectEvents({
@Expect(type = DistributionSetTagCreatedEvent.class, count = 2) })
@ExpectEvents({ @Expect(type = DistributionSetTagCreatedEvent.class, count = 2) })
public void getDistributionSetTags() throws Exception {
final List<DistributionSetTag> tags = testdataFactory.createDistributionSetTags(2);
final DistributionSetTag assigned = tags.get(0);
@@ -162,8 +161,7 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt
@Test
@Description("Verfies that a single result of a DS tag reflects the content on the repository side.")
@ExpectEvents({
@Expect(type = DistributionSetTagCreatedEvent.class, count = 2) })
@ExpectEvents({ @Expect(type = DistributionSetTagCreatedEvent.class, count = 2) })
public void getDistributionSetTag() throws Exception {
final List<DistributionSetTag> tags = testdataFactory.createDistributionSetTags(2);
final DistributionSetTag assigned = tags.get(0);
@@ -181,8 +179,7 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt
@Test
@Description("Verifies that created DS tags are stored in the repository as send to the API.")
@ExpectEvents({
@Expect(type = DistributionSetTagCreatedEvent.class, count = 2) })
@ExpectEvents({ @Expect(type = DistributionSetTagCreatedEvent.class, count = 2) })
public void createDistributionSetTags() throws Exception {
final Tag tagOne = entityFactory.tag().create().colour("testcol1").description("its a test1").name("thetest1")
.build();

View File

@@ -68,8 +68,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
@Test
@Description("Verfies that a paged result list of target tags reflects the content on the repository side.")
@ExpectEvents({
@Expect(type = TargetTagCreatedEvent.class, count = 2) })
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 2) })
public void getTargetTags() throws Exception {
final List<TargetTag> tags = testdataFactory.createTargetTags(2, "");
final TargetTag assigned = tags.get(0);
@@ -132,8 +131,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
@Test
@Description("Verfies that a single result of a target tag reflects the content on the repository side.")
@ExpectEvents({
@Expect(type = TargetTagCreatedEvent.class, count = 2) })
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 2) })
public void getTargetTag() throws Exception {
final List<TargetTag> tags = testdataFactory.createTargetTags(2, "");
final TargetTag assigned = tags.get(0);
@@ -152,8 +150,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
@Test
@Description("Verifies that created target tags are stored in the repository as send to the API.")
@ExpectEvents({
@Expect(type = TargetTagCreatedEvent.class, count = 2) })
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 2) })
public void createTargetTags() throws Exception {
final Tag tagOne = entityFactory.tag().create().colour("testcol1").description("its a test1").name("thetest1")
.build();

View File

@@ -278,8 +278,8 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
final Collection<JpaSoftwareModuleType> foundModules =
softwareModuleTypeRepository.findAllById(softwareModulesTypeIds);
if (foundModules.size() < softwareModulesTypeIds.size()) {
throw new EntityNotFoundException(SoftwareModuleType.class, softwareModulesTypeIds,
foundModules.stream().map(SoftwareModuleType::getId).toList());
throw new EntityNotFoundException(
SoftwareModuleType.class, softwareModulesTypeIds, foundModules.stream().map(SoftwareModuleType::getId).toList());
}
final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(dsTypeId);

View File

@@ -27,6 +27,7 @@ import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
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.
@@ -43,9 +44,11 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn
@Serial
private static final long serialVersionUID = 1L;
@Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40)
@Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40) // eclipselink
// @Column(name = "tenant", nullable = false, updatable = false, length = 40) // hibernate
@Size(min = 1, max = 40)
@NotNull
@TenantId // Hibernate MultiTenant support
private String tenant;
/**

View File

@@ -15,9 +15,15 @@ import java.io.Serializable;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Composite key for {@link DistributionSetTypeElement}.
*/
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Data
@Embeddable
public class DistributionSetTypeElementCompositeKey implements Serializable {
@@ -30,75 +36,8 @@ public class DistributionSetTypeElementCompositeKey implements Serializable {
@Column(name = "software_module_type", nullable = false, updatable = false)
private Long smType;
/**
* Default constructor.
*/
DistributionSetTypeElementCompositeKey() {
}
/**
* Constructor.
*
* @param dsType in the key
* @param smType in the key
*/
DistributionSetTypeElementCompositeKey(final JpaDistributionSetType dsType, final JpaSoftwareModuleType smType) {
this.dsType = dsType.getId();
this.smType = smType.getId();
}
public Long getDsType() {
return dsType;
}
public void setDsType(final Long dsType) {
this.dsType = dsType;
}
public Long getSmType() {
return smType;
}
public void setSmType(final Long smType) {
this.smType = smType;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dsType == null) ? 0 : dsType.hashCode());
result = prime * result + ((smType == null) ? 0 : smType.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final DistributionSetTypeElementCompositeKey other = (DistributionSetTypeElementCompositeKey) obj;
if (dsType == null) {
if (other.dsType != null) {
return false;
}
} else if (!dsType.equals(other.dsType)) {
return false;
}
if (smType == null) {
if (other.smType != null) {
return false;
}
} else if (!smType.equals(other.smType)) {
return false;
}
return true;
}
}
}

View File

@@ -22,7 +22,6 @@ import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.model.AutoConfirmationStatus;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.Target;

View File

@@ -79,22 +79,26 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Setter
@ManyToOne(fetch = FetchType.LAZY, optional = false, targetEntity = JpaDistributionSetType.class)
@JoinColumn(name = "ds_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds"))
@JoinColumn(
name = "ds_id", nullable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds"))
@NotNull
private DistributionSetType type;
@ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY)
@ManyToMany(
targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY,
cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinTable(
name = "sp_ds_module",
joinColumns = {
@JoinColumn(
name = "ds_id", nullable = false, insertable = false, updatable = false, foreignKey =
@ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) },
name = "ds_id", nullable = false, insertable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) },
inverseJoinColumns = {
@JoinColumn(
name = "module_id", nullable = false, insertable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) })
private Set<SoftwareModule> modules;
private Set<SoftwareModule> modules = new HashSet<>();
@ManyToMany(targetEntity = JpaDistributionSetTag.class)
@JoinTable(
@@ -107,11 +111,12 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@JoinColumn(
name = "TAG", nullable = false, insertable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) })
private Set<DistributionSetTag> tags;
private Set<DistributionSetTag> tags = new HashSet<>();
@ToString.Exclude
@OneToMany(mappedBy = "distributionSet", fetch = FetchType.LAZY, cascade = {
CascadeType.REMOVE }, targetEntity = JpaDistributionSetMetadata.class)
@OneToMany(mappedBy = "distributionSet", fetch = FetchType.LAZY,
cascade = { CascadeType.REMOVE },
targetEntity = JpaDistributionSetMetadata.class)
private List<DistributionSetMetadata> metadata;
@Column(name = "complete")
@@ -131,10 +136,8 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Column(name = "required_migration_step")
private boolean requiredMigrationStep;
/**
* Parameterized constructor.
*/
public JpaDistributionSet(final String name, final String version, final String description,
public JpaDistributionSet(
final String name, final String version, final String description,
final DistributionSetType type, final Collection<SoftwareModule> moduleList,
final boolean requiredMigrationStep) {
super(name, version, description);
@@ -152,9 +155,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
this.requiredMigrationStep = requiredMigrationStep;
}
/**
* Parameterized constructor.
*/
public JpaDistributionSet(final String name, final String version, final String description,
final DistributionSetType type, final Collection<SoftwareModule> moduleList) {
this(name, version, description, type, moduleList, false);
@@ -162,10 +162,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Override
public Set<SoftwareModule> getModules() {
if (modules == null) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(modules);
}
@@ -174,10 +170,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
throw new LockedException(JpaDistributionSet.class, getId(), "ADD_SOFTWARE_MODULE");
}
if (modules == null) {
modules = new HashSet<>();
}
checkTypeCompatability(softwareModule);
final Optional<SoftwareModule> found = modules.stream()
@@ -187,8 +179,7 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
return;
}
final long already = modules.stream()
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count();
final long already = modules.stream().filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count();
if (already >= softwareModule.getType().getMaxAssignments()) {
modules.stream().filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey()))
@@ -211,10 +202,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
}
public Set<DistributionSetTag> getTags() {
if (tags == null) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(tags);
}

View File

@@ -24,7 +24,6 @@ import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;

View File

@@ -75,4 +75,4 @@ public class JpaDistributionSetTag extends JpaTag implements DistributionSetTag,
getTenant(), getId(), getClass(), EventPublisherHolder.getInstance().getApplicationId()));
}
}
}

View File

@@ -59,8 +59,10 @@ public class JpaDistributionSetType extends AbstractJpaTypeEntity implements Dis
@Serial
private static final long serialVersionUID = 1L;
@OneToMany(mappedBy = "dsType", targetEntity = DistributionSetTypeElement.class, fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST,
CascadeType.REMOVE }, orphanRemoval = true)
@OneToMany(mappedBy = "dsType",
targetEntity = DistributionSetTypeElement.class,
fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE },
orphanRemoval = true)
private Set<DistributionSetTypeElement> elements = new HashSet<>();
@Setter

View File

@@ -67,5 +67,4 @@ public class JpaSoftwareModuleMetadata extends AbstractJpaMetaData implements So
public SwMetadataCompositeKey getId() {
return new SwMetadataCompositeKey(softwareModule.getId(), getKey());
}
}

View File

@@ -85,7 +85,7 @@ public interface DistributionSetRepository extends BaseEntityRepository<JpaDistr
* @param ids to search for
* @return list of {@link DistributionSet#getId()}
*/
@Query("select ac.distributionSet.id from JpaAction ac where ac.distributionSet.id in :ids")
@Query("SELECT ac.distributionSet.id FROM JpaAction ac WHERE ac.distributionSet.id IN :ids")
List<Long> findAssignedToTargetDistributionSetsById(@Param("ids") Collection<Long> ids);
/**
@@ -97,7 +97,7 @@ public interface DistributionSetRepository extends BaseEntityRepository<JpaDistr
* @param ids to search for
* @return list of {@link DistributionSet#getId()}
*/
@Query("select ra.distributionSet.id from JpaRollout ra where ra.distributionSet.id in :ids")
@Query("SELECT ra.distributionSet.id FROM JpaRollout ra WHERE ra.distributionSet.id IN :ids")
List<Long> findAssignedToRolloutDistributionSetsById(@Param("ids") Collection<Long> ids);
/**

View File

@@ -23,31 +23,24 @@ import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
/**
* {@link PagingAndSortingRepository} and {@link org.springframework.data.repository.CrudRepository} for
* {@link DistributionSetType}.
* {@link PagingAndSortingRepository} and {@link org.springframework.data.repository.CrudRepository} for {@link DistributionSetType}.
*/
@Transactional(readOnly = true)
public interface DistributionSetTypeRepository
extends BaseEntityRepository<JpaDistributionSetType> {
public interface DistributionSetTypeRepository extends BaseEntityRepository<JpaDistributionSetType> {
/**
* Counts all distribution set type where a specific software module type is
* assigned to.
* Counts all distribution set type where a specific software module type is assigned to.
* <p/>
* No access control applied
*
* @param softwareModuleType the software module type to count the distribution set type
* which has this software module type assigned
* @return the number of {@link DistributionSetType}s in the repository
* assigned to the given software module type
* @param softwareModuleType the software module type to count the distribution set type which has this software module type assigned
* @return the number of {@link DistributionSetType}s in the repository assigned to the given software module type
*/
long countByElementsSmType(JpaSoftwareModuleType softwareModuleType);
/**
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety
* reasons (this is a "delete everything" query after all) we add the tenant
* manually to query even if this will by done by {@link EntityManager}
* anyhow. The DB should take care of optimizing this away.
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety reasons (this is a "delete everything" query after all) we add
* the tenant manually to query even if this will by done by {@link EntityManager} anyhow. The DB should take care of optimizing this away.
*
* @param tenant to delete data from
*/
@@ -57,8 +50,7 @@ public interface DistributionSetTypeRepository
void deleteByTenant(@Param("tenant") String tenant);
/**
* Counts the {@link SoftwareModuleType}s which are associated with the
* addressed {@link DistributionSetType}.
* Counts the {@link SoftwareModuleType}s which are associated with the addressed {@link DistributionSetType}.
* <p/>
* No access control applied
*
@@ -67,4 +59,4 @@ public interface DistributionSetTypeRepository
*/
@Query("SELECT COUNT (e.smType) FROM DistributionSetTypeElement e WHERE e.dsType.id = :id")
long countSmTypesById(@Param("id") Long id);
}
}

View File

@@ -91,4 +91,4 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget> {
@Transactional
@Query("DELETE FROM JpaTarget t WHERE t.tenant = :tenant")
void deleteByTenant(@Param("tenant") String tenant);
}
}

View File

@@ -97,4 +97,4 @@ public final class SoftwareModuleSpecification {
return cb.conjunction();
};
}
}
}

View File

@@ -1584,8 +1584,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Delete a target with a non existing thingId")
@ExpectEvents({
@Expect(type = TargetDeletedEvent.class, count = 0) })
@ExpectEvents({ @Expect(type = TargetDeletedEvent.class, count = 0) })
void deleteTargetWithInvalidThingId() {
assertThatExceptionOfType(EntityNotFoundException.class)
.as("No EntityNotFoundException thrown when deleting a non-existing target")

View File

@@ -134,7 +134,6 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
@Test
@Description("Verifies that the quota for software module types per distribution set type is enforced as expected.")
public void quotaMaxSoftwareModuleTypes() {
final int quota = quotaManagement.getMaxSoftwareModuleTypesPerDistributionSetType();
// create software module types
final List<Long> moduleTypeIds = new ArrayList<>();
@@ -168,8 +167,7 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
// assign as many optional modules as possible
final DistributionSetType dsType3 = distributionSetTypeManagement
.create(entityFactory.distributionSetType().create().key("dst3").name("dst3"));
distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(dsType3.getId(),
moduleTypeIds.subList(0, quota));
distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(dsType3.getId(), moduleTypeIds.subList(0, quota));
assertThat(distributionSetTypeManagement.get(dsType3.getId())).isNotEmpty();
assertThat(distributionSetTypeManagement.get(dsType3.getId()).get().getOptionalModuleTypes().size())
.isEqualTo(quota);

View File

@@ -491,7 +491,6 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Checks that metadata for a software module can be created.")
public void createSoftwareModuleMetadata() {
final String knownKey1 = "myKnownKey1";
final String knownValue1 = "myKnownValue1";