Small JPA improvements & test code style (#2122)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -553,7 +553,9 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
|
||||
|
||||
@Override
|
||||
public void deleteExistingTarget(@NotEmpty final String controllerId) {
|
||||
targetRepository.deleteById(targetRepository.getByControllerId(controllerId).getId());
|
||||
final JpaTarget target = targetRepository.getByControllerId(controllerId);
|
||||
targetRepository.deleteById(target.getId());
|
||||
entityManager.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -421,7 +421,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
|
||||
@Override
|
||||
public Optional<DistributionSet> getWithDetails(final long id) {
|
||||
return distributionSetRepository.findById(id).map(DistributionSet.class::cast);
|
||||
return distributionSetRepository
|
||||
.findOne(distributionSetRepository.byIdSpec(id), JpaDistributionSet_.GRAPH_DISTRIBUTION_SET_DETAIL)
|
||||
.map(DistributionSet.class::cast);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -128,12 +128,9 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
||||
* @param properties properties to get the underlying database
|
||||
*/
|
||||
public JpaSystemManagement(final JpaProperties properties) {
|
||||
|
||||
final String isDeleted = isPostgreSql(properties) ? "false" : "0";
|
||||
countArtifactQuery = "SELECT COUNT(a.id) FROM sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = "
|
||||
+ isDeleted;
|
||||
countSoftwareModulesQuery = "select SUM(file_size) from sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = "
|
||||
+ isDeleted;
|
||||
countArtifactQuery = "SELECT COUNT(a.id) FROM sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = " + isDeleted;
|
||||
countSoftwareModulesQuery = "select SUM(file_size) from sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = " + isDeleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -198,8 +198,8 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
|
||||
@Override
|
||||
public long countByRsqlAndCompatible(final String targetFilterQuery, final Long distributionSetIdTypeId) {
|
||||
final List<Specification<JpaTarget>> specList = List.of(RSQLUtility.buildRsqlSpecification(targetFilterQuery,
|
||||
TargetFields.class, virtualPropertyReplacer, database),
|
||||
final List<Specification<JpaTarget>> specList = List.of(RSQLUtility.buildRsqlSpecification(
|
||||
targetFilterQuery, TargetFields.class, virtualPropertyReplacer, database),
|
||||
TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId));
|
||||
|
||||
return JpaManagementHelper.countBySpec(targetRepository, specList);
|
||||
@@ -207,8 +207,8 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
|
||||
@Override
|
||||
public long countByRsqlAndCompatibleAndUpdatable(String targetFilterQuery, Long distributionSetIdTypeId) {
|
||||
final List<Specification<JpaTarget>> specList = List.of(RSQLUtility.buildRsqlSpecification(targetFilterQuery,
|
||||
TargetFields.class, virtualPropertyReplacer, database),
|
||||
final List<Specification<JpaTarget>> specList = List.of(RSQLUtility.buildRsqlSpecification(
|
||||
targetFilterQuery, TargetFields.class, virtualPropertyReplacer, database),
|
||||
TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId));
|
||||
return targetRepository.count(AccessController.Operation.UPDATE, combineWithAnd(specList));
|
||||
}
|
||||
|
||||
@@ -58,6 +58,12 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Version
|
||||
@Column(name = "optlock_revision")
|
||||
private int optLockRevision;
|
||||
|
||||
// Audit fields. use property access to ensure that setters will be called and checked for modification
|
||||
// (touch implementation depends on setLastModifiedAt(0).
|
||||
@Column(name = "created_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH)
|
||||
private String createdBy;
|
||||
@Column(name = "created_at", updatable = false, nullable = false)
|
||||
@@ -67,10 +73,6 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
@Column(name = "last_modified_at", nullable = false)
|
||||
private long lastModifiedAt;
|
||||
|
||||
@Version
|
||||
@Column(name = "optlock_revision")
|
||||
private int optLockRevision;
|
||||
|
||||
@CreatedBy
|
||||
public void setCreatedBy(final String createdBy) {
|
||||
if (isController()) {
|
||||
@@ -170,14 +172,16 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
return false;
|
||||
}
|
||||
final AbstractJpaBaseEntity other = (AbstractJpaBaseEntity) obj;
|
||||
final Long id = getId();
|
||||
final Long otherId = other.getId();
|
||||
if (id == null) {
|
||||
if (other.id != null) {
|
||||
if (otherId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!id.equals(other.id)) {
|
||||
} else if (!id.equals(otherId)) {
|
||||
return false;
|
||||
}
|
||||
return optLockRevision == other.optLockRevision;
|
||||
return getOptLockRevision() == other.getOptLockRevision();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Objects;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
@@ -76,11 +77,7 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn
|
||||
return false;
|
||||
}
|
||||
final AbstractJpaTenantAwareBaseEntity other = (AbstractJpaTenantAwareBaseEntity) obj;
|
||||
if (tenant == null) {
|
||||
return other.tenant == null;
|
||||
} else {
|
||||
return tenant.equals(other.tenant);
|
||||
}
|
||||
return Objects.equals(getTenant(), other.getTenant());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.jpa.model;
|
||||
import java.io.Serial;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -36,11 +37,13 @@ import jakarta.persistence.NamedEntityGraph;
|
||||
import jakarta.persistence.NamedEntityGraphs;
|
||||
import jakarta.persistence.NamedSubgraph;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
import lombok.Setter;
|
||||
import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
|
||||
@@ -96,42 +99,65 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
||||
|
||||
@Column(name = "active")
|
||||
private boolean active;
|
||||
|
||||
@Column(name = "action_type", nullable = false)
|
||||
@Convert(converter = ActionTypeConverter.class)
|
||||
@NotNull
|
||||
private ActionType actionType;
|
||||
|
||||
@Column(name = "forced_time")
|
||||
private long forcedTime;
|
||||
|
||||
@Setter
|
||||
@Column(name = "weight")
|
||||
@Min(Action.WEIGHT_MIN)
|
||||
@Max(Action.WEIGHT_MAX)
|
||||
private Integer weight;
|
||||
|
||||
@Column(name = "status", nullable = false)
|
||||
@Convert(converter = StatusConverter.class)
|
||||
@NotNull
|
||||
private Status status;
|
||||
|
||||
@OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE })
|
||||
private List<JpaActionStatus> actionStatus;
|
||||
private List<JpaActionStatus> actionStatus = new ArrayList<>();
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(
|
||||
name = "rolloutgroup", updatable = false,
|
||||
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup"))
|
||||
private JpaRolloutGroup rolloutGroup;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(
|
||||
name = "rollout", updatable = false,
|
||||
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout"))
|
||||
private JpaRollout rollout;
|
||||
|
||||
// a cron expression to be used for scheduling.
|
||||
@Setter
|
||||
@Column(name = "maintenance_cron_schedule", updatable = false, length = Action.MAINTENANCE_WINDOW_SCHEDULE_LENGTH)
|
||||
private String maintenanceWindowSchedule;
|
||||
|
||||
// the duration of an available maintenance schedule indexes HH:mm:ss format
|
||||
@Setter
|
||||
@Column(name = "maintenance_duration", updatable = false, length = Action.MAINTENANCE_WINDOW_DURATION_LENGTH)
|
||||
private String maintenanceWindowDuration;
|
||||
|
||||
// the time zone specified as +/-hh:mm offset from UTC for example +02:00 for CET summer time and +00:00 for UTC. The
|
||||
// start time of a maintenance window calculated based on the cron expression is relative to this time zone.
|
||||
@Setter
|
||||
@Column(name = "maintenance_time_zone", updatable = false, length = Action.MAINTENANCE_WINDOW_TIMEZONE_LENGTH)
|
||||
private String maintenanceWindowTimeZone;
|
||||
|
||||
@Column(name = "external_ref", length = Action.EXTERNAL_REF_MAX_LENGTH)
|
||||
private String externalRef;
|
||||
|
||||
@Setter
|
||||
@Column(name = "initiated_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH)
|
||||
private String initiatedBy;
|
||||
|
||||
@Setter
|
||||
@Column(name = "last_action_status_code", nullable = true, updatable = true)
|
||||
private Integer lastActionStatusCode;
|
||||
|
||||
@@ -194,10 +220,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
||||
return Optional.ofNullable(weight);
|
||||
}
|
||||
|
||||
public void setWeight(final Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroup getRolloutGroup() {
|
||||
return rolloutGroup;
|
||||
@@ -221,47 +243,16 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
||||
return maintenanceWindowSchedule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maintenance schedule.
|
||||
*
|
||||
* @param maintenanceWindowSchedule is a cron expression to be used for scheduling.
|
||||
*/
|
||||
public void setMaintenanceWindowSchedule(final String maintenanceWindowSchedule) {
|
||||
this.maintenanceWindowSchedule = maintenanceWindowSchedule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaintenanceWindowDuration() {
|
||||
return maintenanceWindowDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maintenance window duration.
|
||||
*
|
||||
* @param maintenanceWindowDuration is the duration of an available maintenance schedule in
|
||||
* HH:mm:ss format.
|
||||
*/
|
||||
public void setMaintenanceWindowDuration(final String maintenanceWindowDuration) {
|
||||
this.maintenanceWindowDuration = maintenanceWindowDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaintenanceWindowTimeZone() {
|
||||
return maintenanceWindowTimeZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time zone to be used for maintenance window.
|
||||
*
|
||||
* @param maintenanceWindowTimeZone is the time zone specified as +/-hh:mm offset from UTC for
|
||||
* example +02:00 for CET summer time and +00:00 for UTC. The
|
||||
* start time of a maintenance window calculated based on the
|
||||
* cron expression is relative to this time zone.
|
||||
*/
|
||||
public void setMaintenanceWindowTimeZone(final String maintenanceWindowTimeZone) {
|
||||
this.maintenanceWindowTimeZone = maintenanceWindowTimeZone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExternalRef() {
|
||||
return externalRef;
|
||||
@@ -277,20 +268,15 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
||||
return initiatedBy;
|
||||
}
|
||||
|
||||
public void setInitiatedBy(final String initiatedBy) {
|
||||
this.initiatedBy = initiatedBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> getLastActionStatusCode() {
|
||||
return Optional.ofNullable(lastActionStatusCode);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<ZonedDateTime> getMaintenanceWindowStartTime() {
|
||||
return MaintenanceScheduleHelper.getNextMaintenanceWindow(maintenanceWindowSchedule, maintenanceWindowDuration,
|
||||
maintenanceWindowTimeZone);
|
||||
return MaintenanceScheduleHelper.getNextMaintenanceWindow(
|
||||
maintenanceWindowSchedule, maintenanceWindowDuration, maintenanceWindowTimeZone);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -330,24 +316,15 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
||||
return status == Status.WAIT_FOR_CONFIRMATION;
|
||||
}
|
||||
|
||||
public void setLastActionStatusCode(final Integer lastActionStatusCode) {
|
||||
this.lastActionStatusCode = lastActionStatusCode;
|
||||
}
|
||||
|
||||
public List<ActionStatus> getActionStatus() {
|
||||
if (actionStatus == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(actionStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JpaAction [distributionSet=" + distributionSet.getId() + ", version=" + getOptLockRevision() + ", id="
|
||||
+ getId() + ", actionType=" + getActionType() + ", weight=" + getWeight() + ", isActive=" + isActive()
|
||||
+ ", createdAt=" + getCreatedAt() + ", lastModifiedAt=" + getLastModifiedAt() + ", status="
|
||||
+ getStatus().name() + "]";
|
||||
return "JpaAction [distributionSet=" + distributionSet.getId() + ", version=" + getOptLockRevision() + ", id=" + getId() +
|
||||
", actionType=" + getActionType() + ", weight=" + getWeight() + ", isActive=" + isActive() +
|
||||
", createdAt=" + getCreatedAt() + ", lastModifiedAt=" + getLastModifiedAt() + ", status=" + getStatus().name() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -132,7 +132,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@ManyToOne(optional = true, fetch = FetchType.LAZY)
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "installed_distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds"))
|
||||
private JpaDistributionSet installedDistributionSet;
|
||||
|
||||
|
||||
@@ -10,20 +10,18 @@
|
||||
package org.eclipse.hawkbit.repository.jpa.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import jakarta.persistence.EntityGraph;
|
||||
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;
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
@@ -43,6 +41,10 @@ public interface BaseEntityRepository<T extends AbstractJpaTenantAwareBaseEntity
|
||||
extends PagingAndSortingRepository<T, Long>, CrudRepository<T, Long>, JpaSpecificationExecutor<T>,
|
||||
JpaSpecificationEntityGraphExecutor<T>, NoCountSliceRepository<T>, ACMRepository<T> {
|
||||
|
||||
default T getById(final Long id) {
|
||||
return findOne(byIdSpec(id)).orElseThrow(() -> new EntityNotFoundException(getManagementClass(), id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides {@link org.springframework.data.repository.CrudRepository#saveAll(Iterable)} to return a list of created entities instead
|
||||
* of an instance of {@link Iterable} to be able to work with it directly in further code processing instead of converting the
|
||||
@@ -133,4 +135,26 @@ public interface BaseEntityRepository<T extends AbstractJpaTenantAwareBaseEntity
|
||||
default Optional<AccessController<T>> getAccessController() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@SuppressWarnings("uchecked")
|
||||
default Class<? extends BaseEntity> getManagementClass() {
|
||||
final Class<T> domainClass = getDomainClass();
|
||||
final String domainClassSimpleName = domainClass.getSimpleName();
|
||||
if (!domainClassSimpleName.toLowerCase().startsWith("jpa")) {
|
||||
return domainClass;
|
||||
}
|
||||
final String managementClassSimpleName = domainClassSimpleName.substring(3);
|
||||
final Class<?> superClass = domainClass.getSuperclass();
|
||||
if (superClass != null) {
|
||||
if (superClass.getSimpleName().equals(managementClassSimpleName) && BaseEntity.class.isAssignableFrom(superClass)) {
|
||||
return (Class<? extends BaseEntity>)superClass;
|
||||
}
|
||||
}
|
||||
for (final Class<?> interfaceClass : domainClass.getInterfaces()) {
|
||||
if (interfaceClass.getSimpleName().equals(managementClassSimpleName) && BaseEntity.class.isAssignableFrom(interfaceClass)) {
|
||||
return (Class<? extends BaseEntity>)interfaceClass;
|
||||
}
|
||||
}
|
||||
return domainClass;
|
||||
}
|
||||
}
|
||||
@@ -290,9 +290,7 @@ public final class TargetSpecifications {
|
||||
public static Specification<JpaTarget> hasNotDistributionSetInActions(final Long distributionSetId) {
|
||||
return (targetRoot, query, cb) -> {
|
||||
final ListJoin<JpaTarget, JpaAction> actionsJoin = targetRoot.join(JpaTarget_.actions, JoinType.LEFT);
|
||||
actionsJoin.on(cb.equal(actionsJoin.get(JpaAction_.distributionSet).get(JpaDistributionSet_.id),
|
||||
distributionSetId));
|
||||
|
||||
actionsJoin.on(cb.equal(actionsJoin.get(JpaAction_.distributionSet).get(JpaDistributionSet_.id), distributionSetId));
|
||||
return cb.isNull(actionsJoin.get(JpaAction_.id));
|
||||
};
|
||||
}
|
||||
@@ -308,10 +306,8 @@ public final class TargetSpecifications {
|
||||
*/
|
||||
public static Specification<JpaTarget> isCompatibleWithDistributionSetType(final Long distributionSetTypeId) {
|
||||
return (targetRoot, query, cb) -> {
|
||||
// Since the targetRoot is changed by joining we need to get the
|
||||
// isNull predicate first
|
||||
// Since the targetRoot is changed by joining we need to get the isNull predicate first
|
||||
final Predicate targetTypeIsNull = getTargetTypeIsNullPredicate(targetRoot);
|
||||
|
||||
return cb.or(targetTypeIsNull, cb.equal(getDsTypeIdPath(targetRoot), distributionSetTypeId));
|
||||
};
|
||||
}
|
||||
@@ -328,15 +324,15 @@ public final class TargetSpecifications {
|
||||
*/
|
||||
public static Specification<JpaTarget> notCompatibleWithDistributionSetType(final Long distributionSetTypeId) {
|
||||
return (targetRoot, query, cb) -> {
|
||||
// Since the targetRoot is changed by joining we need to get the
|
||||
// isNotNull predicate first
|
||||
// Since the targetRoot is changed by joining we need to get the isNotNull predicate first
|
||||
final Predicate targetTypeNotNull = targetRoot.get(JpaTarget_.targetType).isNotNull();
|
||||
|
||||
final Subquery<Long> compatibilitySubQuery = query.subquery(Long.class);
|
||||
final Root<JpaTarget> subQueryTargetRoot = compatibilitySubQuery.from(JpaTarget.class);
|
||||
|
||||
compatibilitySubQuery.select(subQueryTargetRoot.get(JpaTarget_.id))
|
||||
.where(cb.and(cb.equal(targetRoot.get(JpaTarget_.id), subQueryTargetRoot.get(JpaTarget_.id)),
|
||||
.where(cb.and(
|
||||
cb.equal(targetRoot.get(JpaTarget_.id), subQueryTargetRoot.get(JpaTarget_.id)),
|
||||
cb.equal(getDsTypeIdPath(subQueryTargetRoot), distributionSetTypeId)));
|
||||
|
||||
return cb.and(targetTypeNotNull, cb.not(cb.exists(compatibilitySubQuery)));
|
||||
@@ -599,10 +595,6 @@ public final class TargetSpecifications {
|
||||
|
||||
private static Path<Long> getDsTypeIdPath(final Root<JpaTarget> root) {
|
||||
final Join<JpaTarget, JpaTargetType> targetTypeJoin = root.join(JpaTarget_.targetType, JoinType.LEFT);
|
||||
targetTypeJoin.fetch(JpaTargetType_.distributionSetTypes);
|
||||
final SetJoin<JpaTargetType, JpaDistributionSetType> dsTypeTargetTypeJoin = targetTypeJoin
|
||||
.join(JpaTargetType_.distributionSetTypes, JoinType.LEFT);
|
||||
|
||||
return dsTypeTargetTypeJoin.get(JpaDistributionSetType_.id);
|
||||
return targetTypeJoin.join(JpaTargetType_.distributionSetTypes, JoinType.LEFT).get(JpaDistributionSetType_.id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user