JpaSoftwareModule#metadata made map (#2412)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -26,7 +26,6 @@ import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaSoftwareModuleTypeBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaTagBuilder;
|
||||
import org.eclipse.hawkbit.repository.model.MetaData;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,8 +11,8 @@ package org.eclipse.hawkbit.repository.jpa.management;
|
||||
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.DOWNLOADED;
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.FINISHED;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_KEY_SIZE;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_MAX_KEY_SIZE;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_MAX_VALUE_SIZE;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
@@ -618,11 +618,11 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
|
||||
}
|
||||
|
||||
private static boolean isAttributeKeyValid(final String key) {
|
||||
return key != null && key.length() <= CONTROLLER_ATTRIBUTE_KEY_SIZE && PATTERN.matcher(key).matches();
|
||||
return key != null && key.length() <= CONTROLLER_ATTRIBUTE_MAX_KEY_SIZE && PATTERN.matcher(key).matches();
|
||||
}
|
||||
|
||||
private static boolean isAttributeValueValid(final String value) {
|
||||
return value == null || (value.length() <= CONTROLLER_ATTRIBUTE_VALUE_SIZE && PATTERN.matcher(value).matches());
|
||||
return value == null || (value.length() <= CONTROLLER_ATTRIBUTE_MAX_VALUE_SIZE && PATTERN.matcher(value).matches());
|
||||
}
|
||||
|
||||
private static void copy(final Map<String, String> src, final Map<String, String> trg) {
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
package org.eclipse.hawkbit.repository.jpa.management;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -19,7 +18,6 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
|
||||
@@ -29,7 +27,6 @@ import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields;
|
||||
import org.eclipse.hawkbit.repository.builder.GenericSoftwareModuleMetadataUpdate;
|
||||
import org.eclipse.hawkbit.repository.builder.GenericSoftwareModuleUpdate;
|
||||
import org.eclipse.hawkbit.repository.builder.SoftwareModuleCreate;
|
||||
@@ -272,53 +269,61 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public List<SoftwareModuleMetadata> putMetaData(final Collection<SoftwareModuleMetadataCreate> create) {
|
||||
if (!create.isEmpty()) {
|
||||
// check if all metadata entries refer to the same software module
|
||||
final Long id = ((JpaSoftwareModuleMetadataCreate) create.iterator().next()).getSoftwareModuleId();
|
||||
if (createJpaMetadataCreateStream(create).allMatch(c -> id.equals(c.getSoftwareModuleId()))) {
|
||||
assertSoftwareModuleExists(id);
|
||||
assertMetaDataQuota(id, create.size());
|
||||
|
||||
// touch to update revision and last modified timestamp
|
||||
JpaManagementHelper.touch(entityManager, softwareModuleRepository, (JpaSoftwareModule) get(id)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
|
||||
return createJpaMetadataCreateStream(create).map(this::saveMetadata).toList();
|
||||
} else {
|
||||
// group by software module id to minimize database access
|
||||
final Map<Long, List<JpaSoftwareModuleMetadataCreate>> groups = createJpaMetadataCreateStream(create)
|
||||
.collect(Collectors.groupingBy(JpaSoftwareModuleMetadataCreate::getSoftwareModuleId));
|
||||
return groups.entrySet().stream().flatMap(e -> {
|
||||
final List<JpaSoftwareModuleMetadataCreate> group = e.getValue();
|
||||
|
||||
public void createMetadata(final Collection<SoftwareModuleMetadataCreate> create) {
|
||||
// group by software module id to minimize database access
|
||||
create.stream()
|
||||
.map(JpaSoftwareModuleMetadataCreate.class::cast)
|
||||
.collect(Collectors.groupingBy(JpaSoftwareModuleMetadataCreate::getSoftwareModuleId))
|
||||
.forEach((id, createsForSoftwareModule) -> {
|
||||
assertSoftwareModuleExists(id);
|
||||
assertMetaDataQuota(e.getKey(), group.size());
|
||||
assertMetadataQuota(id, createsForSoftwareModule.size());
|
||||
|
||||
// touch to update revision and last modified timestamp
|
||||
JpaManagementHelper.touch(entityManager, softwareModuleRepository, (JpaSoftwareModule) get(id)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
|
||||
return group.stream().map(this::saveMetadata);
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
JpaManagementHelper.touch(
|
||||
entityManager, softwareModuleRepository,
|
||||
(JpaSoftwareModule) get(id).orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
|
||||
createsForSoftwareModule.forEach(this::saveMetadata);
|
||||
});
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Override
|
||||
public List<SoftwareModuleMetadata> getMetadata(final long id) {
|
||||
assertSoftwareModuleExists(id);
|
||||
|
||||
return (List)softwareModuleMetadataRepository.findAll(metadataBySoftwareModuleIdSpec(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoftwareModuleMetadata getMetadata(final long id, final String key) {
|
||||
assertSoftwareModuleExists(id);
|
||||
|
||||
return findMetadata(id, key).orElseThrow(() -> new EntityNotFoundException("SoftwareModuleMetadata", id + ":" + key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleIdAndTargetVisible(final Pageable pageable, final long id) {
|
||||
assertSoftwareModuleExists(id);
|
||||
|
||||
return JpaManagementHelper.convertPage(softwareModuleMetadataRepository.findBySoftwareModuleIdAndTargetVisible(
|
||||
id, true, PageRequest.of(0, RepositoryConstants.MAX_META_DATA_COUNT)), pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public SoftwareModuleMetadata updateMetaData(final SoftwareModuleMetadataCreate c) {
|
||||
public SoftwareModuleMetadata updateMetadata(final SoftwareModuleMetadataCreate c) {
|
||||
final JpaSoftwareModuleMetadataCreate create = (JpaSoftwareModuleMetadataCreate) c;
|
||||
final Long id = create.getSoftwareModuleId();
|
||||
|
||||
assertSoftwareModuleExists(id);
|
||||
assertMetaDataQuota(id, 1);
|
||||
assertMetadataQuota(id, 1);
|
||||
|
||||
// touch to update revision and last modified timestamp
|
||||
JpaManagementHelper.touch(entityManager, softwareModuleRepository, (JpaSoftwareModule) get(id)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
|
||||
JpaManagementHelper.touch(
|
||||
entityManager, softwareModuleRepository,
|
||||
(JpaSoftwareModule) get(id).orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
|
||||
return saveMetadata(create);
|
||||
}
|
||||
|
||||
@@ -326,13 +331,13 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public SoftwareModuleMetadata updateMetaData(final SoftwareModuleMetadataUpdate u) {
|
||||
public SoftwareModuleMetadata updateMetadata(final SoftwareModuleMetadataUpdate u) {
|
||||
final GenericSoftwareModuleMetadataUpdate update = (GenericSoftwareModuleMetadataUpdate) u;
|
||||
|
||||
// check if exists otherwise throw entity not found exception
|
||||
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findMetaDataBySoftwareModuleId(
|
||||
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findMetadata(
|
||||
update.getSoftwareModuleId(), update.getKey())
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModuleMetadata.class, update.getSoftwareModuleId(), update.getKey()));
|
||||
.orElseThrow(() -> new EntityNotFoundException("SoftwareModuleMetadata", update.getSoftwareModuleId() + ":" + update.getKey()));
|
||||
|
||||
update.getValue().ifPresent(metadata::setValue);
|
||||
update.isTargetVisible().ifPresent(metadata::setTargetVisible);
|
||||
@@ -345,9 +350,9 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public void deleteMetaData(final long id, final String key) {
|
||||
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findMetaDataBySoftwareModuleId0(id, key)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModuleMetadata.class, id, key));
|
||||
public void deleteMetadata(final long id, final String key) {
|
||||
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findMetadata(id, key)
|
||||
.orElseThrow(() -> new EntityNotFoundException("SoftwareModuleMetadata", id + ":" + key));
|
||||
|
||||
JpaManagementHelper.touch(entityManager, softwareModuleRepository, metadata.getSoftwareModule());
|
||||
softwareModuleMetadataRepository.deleteById(metadata.getId());
|
||||
@@ -424,45 +429,6 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
||||
.map(SoftwareModule.class::cast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<SoftwareModuleMetadata> findMetaDataBySoftwareModuleId(final long id, final String key) {
|
||||
return findMetaDataBySoftwareModuleId0(id, key);
|
||||
}
|
||||
private Optional<SoftwareModuleMetadata> findMetaDataBySoftwareModuleId0(final long id, final String key) {
|
||||
assertSoftwareModuleExists(id);
|
||||
|
||||
return softwareModuleMetadataRepository.findById(new SwMetadataCompositeKey(id, key))
|
||||
.map(SoftwareModuleMetadata.class::cast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleId(final Pageable pageable, final long id) {
|
||||
assertSoftwareModuleExists(id);
|
||||
|
||||
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleMetadataRepository,
|
||||
Collections.singletonList(metadataBySoftwareModuleIdSpec(id)), pageable
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleIdAndTargetVisible(final Pageable pageable,
|
||||
final long id) {
|
||||
assertSoftwareModuleExists(id);
|
||||
|
||||
return JpaManagementHelper.convertPage(softwareModuleMetadataRepository.findBySoftwareModuleIdAndTargetVisible(
|
||||
id, true, PageRequest.of(0, RepositoryConstants.MAX_META_DATA_COUNT)), pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<SoftwareModuleMetadata> findMetaDataByRsql(final long id, final String rsqlParam, final Pageable pageable) {
|
||||
assertSoftwareModuleExists(id);
|
||||
|
||||
final List<Specification<JpaSoftwareModuleMetadata>> specList = Arrays
|
||||
.asList(RSQLUtility.buildRsqlSpecification(rsqlParam, SoftwareModuleMetadataFields.class,
|
||||
virtualPropertyReplacer, database), metadataBySoftwareModuleIdSpec(id));
|
||||
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleMetadataRepository, specList, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slice<SoftwareModule> findByType(final long typeId, final Pageable pageable) {
|
||||
assertSoftwareModuleTypeExists(typeId);
|
||||
@@ -490,18 +456,6 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
||||
return softwareModuleRepository.count(SoftwareModuleSpecification.byAssignedToDs(distributionSetId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countMetaDataBySoftwareModuleId(final long id) {
|
||||
assertSoftwareModuleExists(id);
|
||||
|
||||
return softwareModuleMetadataRepository.countBySoftwareModuleId(id);
|
||||
}
|
||||
|
||||
private static Stream<JpaSoftwareModuleMetadataCreate> createJpaMetadataCreateStream(
|
||||
final Collection<SoftwareModuleMetadataCreate> create) {
|
||||
return create.stream().map(JpaSoftwareModuleMetadataCreate.class::cast);
|
||||
}
|
||||
|
||||
private static Specification<JpaSoftwareModuleMetadata> metadataBySoftwareModuleIdSpec(final long id) {
|
||||
return (root, query, cb) -> cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule).get(AbstractJpaBaseEntity_.id), id);
|
||||
}
|
||||
@@ -526,23 +480,30 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
||||
return softwareModuleMetadataRepository.save(create.build());
|
||||
}
|
||||
|
||||
private void assertSoftwareModuleMetadataDoesNotExist(final Long id,
|
||||
final JpaSoftwareModuleMetadataCreate md) {
|
||||
private Optional<SoftwareModuleMetadata> findMetadata(final long id, final String key) {
|
||||
assertSoftwareModuleExists(id);
|
||||
|
||||
return softwareModuleMetadataRepository.findById(new SwMetadataCompositeKey(id, key))
|
||||
.map(SoftwareModuleMetadata.class::cast);
|
||||
}
|
||||
|
||||
private void assertSoftwareModuleMetadataDoesNotExist(final Long id, final JpaSoftwareModuleMetadataCreate md) {
|
||||
if (softwareModuleMetadataRepository.existsById(new SwMetadataCompositeKey(id, md.getKey()))) {
|
||||
throw new EntityAlreadyExistsException("Metadata entry with key '" + md.getKey() + "' already exists!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts the meta data quota for the software module with the given ID.
|
||||
* Asserts the meta-data quota for the software module with the given ID.
|
||||
*
|
||||
* @param id The software module ID.
|
||||
* @param requested Number of meta data entries to be created.
|
||||
* @param requested Number of meta-data entries to be created.
|
||||
*/
|
||||
private void assertMetaDataQuota(final Long id, final int requested) {
|
||||
private void assertMetadataQuota(final Long id, final int requested) {
|
||||
final int maxMetaData = quotaManagement.getMaxMetaDataEntriesPerSoftwareModule();
|
||||
QuotaHelper.assertAssignmentQuota(id, requested, maxMetaData, SoftwareModuleMetadata.class,
|
||||
SoftwareModule.class, softwareModuleMetadataRepository::countBySoftwareModuleId);
|
||||
QuotaHelper.assertAssignmentQuota(
|
||||
id, requested, maxMetaData, SoftwareModuleMetadata.class, SoftwareModule.class,
|
||||
softwareModuleMetadataRepository::countBySoftwareModuleId);
|
||||
}
|
||||
|
||||
private void assertSoftwareModuleExists(final Long id) {
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Objects;
|
||||
|
||||
import jakarta.persistence.Basic;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.MetaData;
|
||||
|
||||
/**
|
||||
* Meta data for entities.
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public abstract class AbstractJpaMetaData implements MetaData {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@Column(name = "meta_key", nullable = false, length = MetaData.KEY_MAX_SIZE, updatable = false)
|
||||
@Size(min = 1, max = MetaData.KEY_MAX_SIZE)
|
||||
@NotNull
|
||||
private String key;
|
||||
|
||||
@Column(name = "meta_value", length = MetaData.VALUE_MAX_SIZE)
|
||||
@Size(max = MetaData.VALUE_MAX_SIZE)
|
||||
@Basic
|
||||
private String value;
|
||||
|
||||
protected AbstractJpaMetaData(final String key, final String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
protected AbstractJpaMetaData() {
|
||||
// Default constructor needed for JPA entities
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(final String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
final AbstractJpaMetaData that = (AbstractJpaMetaData) o;
|
||||
return Objects.equals(key, that.key) && Objects.equals(value, that.value);
|
||||
}
|
||||
}
|
||||
@@ -116,8 +116,8 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
|
||||
name = "sp_ds_metadata",
|
||||
joinColumns = { @JoinColumn(name = "ds", nullable = false) },
|
||||
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_metadata_ds"))
|
||||
@MapKeyColumn(name = "meta_key", length = DistributionSet.METADATA_KEY_SIZE)
|
||||
@Column(name = "meta_value", length = DistributionSet.METADATA_VALUE_SIZE)
|
||||
@MapKeyColumn(name = "meta_key", length = DistributionSet.METADATA_MAX_KEY_SIZE)
|
||||
@Column(name = "meta_value", length = DistributionSet.METADATA_MAX_VALUE_SIZE)
|
||||
private Map<String, String> metadata;
|
||||
|
||||
@Column(name = "complete")
|
||||
|
||||
@@ -13,10 +13,13 @@ import java.io.Serial;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.CollectionTable;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.ForeignKey;
|
||||
@@ -24,6 +27,7 @@ import jakarta.persistence.Index;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapKeyColumn;
|
||||
import jakarta.persistence.NamedAttributeNode;
|
||||
import jakarta.persistence.NamedEntityGraph;
|
||||
import jakarta.persistence.OneToMany;
|
||||
@@ -69,8 +73,6 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String DELETED_PROPERTY = "deleted";
|
||||
|
||||
@Setter
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "sm_type", nullable = false, updatable = false,
|
||||
@@ -92,11 +94,16 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
|
||||
@Column(name = "encrypted")
|
||||
private boolean encrypted;
|
||||
|
||||
@ToString.Exclude
|
||||
@OneToMany(mappedBy = "softwareModule", fetch = FetchType.LAZY,
|
||||
cascade = { CascadeType.REMOVE },
|
||||
targetEntity = JpaSoftwareModuleMetadata.class)
|
||||
private List<JpaSoftwareModuleMetadata> metadata;
|
||||
// no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent.
|
||||
@Getter
|
||||
@ElementCollection
|
||||
@CollectionTable(
|
||||
name = "sp_sm_metadata",
|
||||
joinColumns = { @JoinColumn(name = "sm", nullable = false) },
|
||||
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_sm_metadata_sm"))
|
||||
@MapKeyColumn(name = "meta_key", length = SoftwareModule.METADATA_KEY_MAX_SIZE)
|
||||
@Column(name = "meta_value", length = SoftwareModule.METADATA_VALUE_MAX_SIZE)
|
||||
private Map<String, String> metadata;
|
||||
|
||||
@Column(name = "locked")
|
||||
private boolean locked;
|
||||
|
||||
@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import jakarta.persistence.Basic;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
import jakarta.persistence.Entity;
|
||||
@@ -21,11 +22,11 @@ import jakarta.persistence.IdClass;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
|
||||
|
||||
@@ -34,31 +35,42 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
|
||||
*/
|
||||
@NoArgsConstructor // Default constructor for JPA
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@IdClass(SwMetadataCompositeKey.class)
|
||||
@Entity
|
||||
@Table(name = "sp_sm_metadata")
|
||||
public class JpaSoftwareModuleMetadata extends AbstractJpaMetaData implements SoftwareModuleMetadata {
|
||||
public class JpaSoftwareModuleMetadata implements SoftwareModuleMetadata {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch = FetchType.LAZY, optional = false)
|
||||
@JoinColumn(name = "sm", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_sm_metadata_sm"))
|
||||
@JoinColumn(
|
||||
name = "sm", nullable = false, updatable = false,
|
||||
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_sm_metadata_sm"))
|
||||
private JpaSoftwareModule softwareModule;
|
||||
|
||||
@Id
|
||||
@Column(name = "meta_key", nullable = false, length = SoftwareModule.METADATA_KEY_MAX_SIZE, updatable = false)
|
||||
@Size(min = 1, max = SoftwareModule.METADATA_KEY_MAX_SIZE)
|
||||
@NotNull
|
||||
private String key;
|
||||
|
||||
@Column(name = "meta_value", length = SoftwareModule.METADATA_VALUE_MAX_SIZE)
|
||||
@Size(max = SoftwareModule.METADATA_VALUE_MAX_SIZE)
|
||||
@Basic
|
||||
private String value;
|
||||
|
||||
@Column(name = "target_visible")
|
||||
private boolean targetVisible;
|
||||
|
||||
public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value) {
|
||||
super(key, value);
|
||||
this.softwareModule = (JpaSoftwareModule) softwareModule;
|
||||
this(key, softwareModule, value, false);
|
||||
}
|
||||
|
||||
public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value, final boolean targetVisible) {
|
||||
super(key, value);
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.softwareModule = (JpaSoftwareModule) softwareModule;
|
||||
this.targetVisible = targetVisible;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import jakarta.persistence.MapKeyColumn;
|
||||
import jakarta.persistence.NamedAttributeNode;
|
||||
import jakarta.persistence.NamedEntityGraph;
|
||||
import jakarta.persistence.NamedEntityGraphs;
|
||||
import jakarta.persistence.NamedSubgraph;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.PrimaryKeyJoinColumn;
|
||||
import jakarta.persistence.Table;
|
||||
@@ -187,8 +186,8 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
|
||||
name = "sp_target_attributes",
|
||||
joinColumns = { @JoinColumn(name = "target", nullable = false) },
|
||||
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_attributes_target"))
|
||||
@MapKeyColumn(name = "attribute_key", length = Target.CONTROLLER_ATTRIBUTE_KEY_SIZE)
|
||||
@Column(name = "attribute_value", length = Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE)
|
||||
@MapKeyColumn(name = "attribute_key", length = Target.CONTROLLER_ATTRIBUTE_MAX_KEY_SIZE)
|
||||
@Column(name = "attribute_value", length = Target.CONTROLLER_ATTRIBUTE_MAX_VALUE_SIZE)
|
||||
private Map<String, String> controllerAttributes;
|
||||
|
||||
// no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent
|
||||
@@ -198,8 +197,8 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
|
||||
name = "sp_target_metadata",
|
||||
joinColumns = { @JoinColumn(name = "target", nullable = false) },
|
||||
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_metadata_target"))
|
||||
@MapKeyColumn(name = "meta_key", length = Target.CONTROLLER_METADATA_KEY_SIZE)
|
||||
@Column(name = "meta_value", length = Target.CONTROLLER_METADATA_VALUE_SIZE)
|
||||
@MapKeyColumn(name = "meta_key", length = Target.METADATA_MAX_KEY_SIZE)
|
||||
@Column(name = "meta_value", length = Target.METADATA_MAX_VALUE_SIZE)
|
||||
private Map<String, String> metadata;
|
||||
|
||||
@OneToMany(mappedBy = "target", fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, targetEntity = JpaAction.class)
|
||||
|
||||
Reference in New Issue
Block a user