Browse Source

removed relation by profile processing

pull/14141/head
IrynaMatveieva 12 months ago
parent
commit
e6479d5856
  1. 16
      application/src/main/java/org/thingsboard/server/service/queue/processing/AbstractConsumerService.java
  2. 15
      common/dao-api/src/main/java/org/thingsboard/server/dao/relation/RelationService.java
  3. 30
      common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/aggregation/AggSource.java
  4. 21
      common/data/src/main/java/org/thingsboard/server/common/data/relation/ProfileEntityRelationPathQuery.java
  5. 100
      dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java
  6. 7
      dao/src/main/java/org/thingsboard/server/dao/relation/RelationCacheKey.java
  7. 7
      dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java
  8. 108
      dao/src/main/java/org/thingsboard/server/dao/sql/relation/JpaRelationDao.java
  9. 36
      dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java

16
application/src/main/java/org/thingsboard/server/service/queue/processing/AbstractConsumerService.java

@ -188,13 +188,9 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
deviceProfileCache.evict(tenantId, new DeviceId(componentLifecycleMsg.getEntityId().getId()));
if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.CREATED)) {
calculatedFieldCache.addOwnerEntity(tenantId, componentLifecycleMsg.getEntityId());
} else if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.UPDATED)) {
actorContext.getRelationService().evictRelationsByEntityAndProfile(tenantId, componentLifecycleMsg.getEntityId(), componentLifecycleMsg.getOldProfileId());
if (componentLifecycleMsg.isOwnerChanged()) {
calculatedFieldCache.updateOwnerEntity(tenantId, componentLifecycleMsg.getEntityId());
}
} else if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.UPDATED) && componentLifecycleMsg.isOwnerChanged()) {
calculatedFieldCache.updateOwnerEntity(tenantId, componentLifecycleMsg.getEntityId());
} else if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.DELETED)) {
actorContext.getRelationService().evictRelationsByEntityAndProfile(tenantId, componentLifecycleMsg.getEntityId(), componentLifecycleMsg.getOldProfileId());
calculatedFieldCache.evictEntity(componentLifecycleMsg.getEntityId());
}
} else if (EntityType.ASSET_PROFILE.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
@ -203,13 +199,9 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
assetProfileCache.evict(tenantId, new AssetId(componentLifecycleMsg.getEntityId().getId()));
if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.CREATED)) {
calculatedFieldCache.addOwnerEntity(tenantId, componentLifecycleMsg.getEntityId());
} else if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.UPDATED)) {
actorContext.getRelationService().evictRelationsByEntityAndProfile(tenantId, componentLifecycleMsg.getEntityId(), componentLifecycleMsg.getOldProfileId());
if (componentLifecycleMsg.isOwnerChanged()) {
calculatedFieldCache.updateOwnerEntity(tenantId, componentLifecycleMsg.getEntityId());
}
} else if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.UPDATED) && componentLifecycleMsg.isOwnerChanged()) {
calculatedFieldCache.updateOwnerEntity(tenantId, componentLifecycleMsg.getEntityId());
} else if (componentLifecycleMsg.getEvent().equals(ComponentLifecycleEvent.DELETED)) {
actorContext.getRelationService().evictRelationsByEntityAndProfile(tenantId, componentLifecycleMsg.getEntityId(), componentLifecycleMsg.getOldProfileId());
calculatedFieldCache.evictEntity(componentLifecycleMsg.getEntityId());
}
} else if (EntityType.ENTITY_VIEW.equals(componentLifecycleMsg.getEntityId().getEntityType())) {

15
common/dao-api/src/main/java/org/thingsboard/server/dao/relation/RelationService.java

@ -22,7 +22,6 @@ import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationInfo;
import org.thingsboard.server.common.data.relation.EntityRelationPathQuery;
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
import org.thingsboard.server.common.data.relation.ProfileEntityRelationPathQuery;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChainType;
@ -87,20 +86,6 @@ public interface RelationService {
ListenableFuture<List<EntityRelation>> findByRelationPathQueryAsync(TenantId tenantId, EntityRelationPathQuery relationPathQuery);
ListenableFuture<List<EntityRelation>> findByProfileEntityRelationPathQueryAsync(TenantId tenantId, ProfileEntityRelationPathQuery relationPathQuery);
List<EntityRelation> findByProfileEntityRelationPathQuery(TenantId tenantId, ProfileEntityRelationPathQuery relationPathQuery);
ListenableFuture<List<EntityRelation>> findByFromAndTypeAndEntityProfileAsync(TenantId tenantId, EntityId from, String relationType, EntityId targetProfileId);
List<EntityRelation> findByFromAndTypeAndEntityProfile(TenantId tenantId, EntityId from, String relationType, EntityId profileId);
ListenableFuture<List<EntityRelation>> findByToAndTypeAndEntityProfileAsync(TenantId tenantId, EntityId to, String relationType, EntityId targetProfileId);
List<EntityRelation> findByToAndTypeAndEntityProfile(TenantId tenantId, EntityId to, String relationType, EntityId profileId);
void evictRelationsByEntityAndProfile(TenantId tenantId, EntityId entityId, EntityId profileId);
// TODO: This method may be useful for some validations in the future
// ListenableFuture<Boolean> checkRecursiveRelation(EntityId from, EntityId to);

30
common/data/src/main/java/org/thingsboard/server/common/data/cf/configuration/aggregation/AggSource.java

@ -1,30 +0,0 @@
/**
* Copyright © 2016-2025 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.cf.configuration.aggregation;
import lombok.Data;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.relation.RelationPathLevel;
import java.util.List;
@Data
public class AggSource {
private RelationPathLevel relation;
private List<EntityId> entityProfiles;
}

21
common/data/src/main/java/org/thingsboard/server/common/data/relation/ProfileEntityRelationPathQuery.java

@ -1,21 +0,0 @@
/**
* Copyright © 2016-2025 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.relation;
import org.thingsboard.server.common.data.id.EntityId;
public record ProfileEntityRelationPathQuery(EntityId rootEntityId, RelationPathLevel level, EntityId targetEntityProfileId) {
}

100
dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java

@ -45,7 +45,6 @@ import org.thingsboard.server.common.data.relation.EntityRelationInfo;
import org.thingsboard.server.common.data.relation.EntityRelationPathQuery;
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.ProfileEntityRelationPathQuery;
import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter;
import org.thingsboard.server.common.data.relation.RelationPathLevel;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
@ -515,105 +514,6 @@ public class BaseRelationService implements RelationService {
return executor.submit(() -> relationDao.findByRelationPathQuery(tenantId, relationPathQuery));
}
@Override
public ListenableFuture<List<EntityRelation>> findByProfileEntityRelationPathQueryAsync(TenantId tenantId, ProfileEntityRelationPathQuery relationPathQuery) {
log.trace("Executing findByProfileEntityRelationPathQueryAsync, tenantId [{}], relationPathQuery {}", tenantId, relationPathQuery);
validateId(tenantId, id -> "Invalid tenant id: " + id);
validate(relationPathQuery);
RelationPathLevel relationPathLevel = relationPathQuery.level();
return switch (relationPathLevel.direction()) {
case FROM -> findByFromAndTypeAndEntityProfileAsync(tenantId, relationPathQuery.rootEntityId(), relationPathLevel.relationType(), relationPathQuery.targetEntityProfileId());
case TO -> findByToAndTypeAndEntityProfileAsync(tenantId, relationPathQuery.rootEntityId(), relationPathLevel.relationType(), relationPathQuery.targetEntityProfileId());
};
}
@Override
public List<EntityRelation> findByProfileEntityRelationPathQuery(TenantId tenantId, ProfileEntityRelationPathQuery relationPathQuery) {
log.trace("Executing findByProfileEntityRelationPathQuery, tenantId [{}], relationPathQuery {}", tenantId, relationPathQuery);
validateId(tenantId, id -> "Invalid tenant id: " + id);
validate(relationPathQuery);
return relationDao.findByProfileEntityRelationPathQuery(tenantId, relationPathQuery);
// RelationPathLevel relationPathLevel = relationPathQuery.level();
// return switch (relationPathLevel.direction()) {
// case FROM -> findByFromAndTypeAndEntityProfile(tenantId, relationPathQuery.rootEntityId(), relationPathLevel.relationType(), relationPathQuery.targetEntityProfileId());
// case TO -> findByToAndTypeAndEntityProfile(tenantId, relationPathQuery.rootEntityId(), relationPathLevel.relationType(), relationPathQuery.targetEntityProfileId());
// };
}
@Override
public ListenableFuture<List<EntityRelation>> findByFromAndTypeAndEntityProfileAsync(TenantId tenantId, EntityId from, String relationType, EntityId targetProfileId) {
log.trace("Executing findByFromAndTypeAndEntityProfileAsync [{}][{}][{}]", from, relationType, targetProfileId);
validate(from);
validateType(relationType);
if (targetProfileId == null) {
return findByFromAndTypeAsync(tenantId, from, relationType, RelationTypeGroup.COMMON);
}
return executor.submit(() -> findByFromAndTypeAndEntityProfile(tenantId, from, relationType, targetProfileId));
}
@Override
public List<EntityRelation> findByFromAndTypeAndEntityProfile(TenantId tenantId, EntityId from, String relationType, EntityId targetProfileId) {
if (targetProfileId == null) {
return findByFromAndType(tenantId, from, relationType, RelationTypeGroup.COMMON);
}
// RelationCacheKey cacheKey = RelationCacheKey.builder().from(from).type(relationType).typeGroup(RelationTypeGroup.COMMON).direction(EntitySearchDirection.FROM).entityProfile(targetProfileId).build();
// return cache.getAndPutInTransaction(cacheKey,
// () -> relationDao.findByFromAndTypeAndProfile(tenantId, from, relationType, RelationTypeGroup.COMMON, targetProfileId),
// RelationCacheValue::getRelations,
// relations -> RelationCacheValue.builder().relations(relations).build(), false);
return relationDao.findByFromAndTypeAndProfile(tenantId, from, relationType, RelationTypeGroup.COMMON, targetProfileId);
}
@Override
public ListenableFuture<List<EntityRelation>> findByToAndTypeAndEntityProfileAsync(TenantId tenantId, EntityId to, String relationType, EntityId targetProfileId) {
log.trace("Executing findByToAndTypeAndEntityProfileAsync [{}][{}][{}]", to, relationType, targetProfileId);
validate(to);
validateType(relationType);
if (targetProfileId == null) {
return findByToAndTypeAsync(tenantId, to, relationType, RelationTypeGroup.COMMON);
}
return executor.submit(() -> findByToAndTypeAndEntityProfile(tenantId, to, relationType, targetProfileId));
}
@Override
public List<EntityRelation> findByToAndTypeAndEntityProfile(TenantId tenantId, EntityId to, String relationType, EntityId targetProfileId) {
if (targetProfileId == null) {
return findByFromAndType(tenantId, to, relationType, RelationTypeGroup.COMMON);
}
// RelationCacheKey cacheKey = RelationCacheKey.builder().to(to).type(relationType).typeGroup(RelationTypeGroup.COMMON).direction(EntitySearchDirection.TO).entityProfile(targetProfileId).build();
// return cache.getAndPutInTransaction(cacheKey,
// () -> relationDao.findByToAndTypeAndProfile(tenantId, to, relationType, RelationTypeGroup.COMMON, targetProfileId),
// RelationCacheValue::getRelations,
// relations -> RelationCacheValue.builder().relations(relations).build(), false);
return relationDao.findByToAndTypeAndProfile(tenantId, to, relationType, RelationTypeGroup.COMMON, targetProfileId);
}
@Override
public void evictRelationsByEntityAndProfile(TenantId tenantId, EntityId entityId, EntityId profileId) {
// List<RelationCacheKey> keys = new ArrayList<>(5);
// keys.add(new RelationCacheKey(entityId, null, event.getType(), event.getTypeGroup()));
// keys.add(new RelationCacheKey(event.getFrom(), null, event.getType(), event.getTypeGroup(), EntitySearchDirection.FROM));
// keys.add(new RelationCacheKey(event.getFrom(), null, null, event.getTypeGroup(), EntitySearchDirection.FROM));
// keys.add(new RelationCacheKey(null, event.getTo(), event.getType(), event.getTypeGroup(), EntitySearchDirection.TO));
// keys.add(new RelationCacheKey(null, event.getTo(), null, event.getTypeGroup(), EntitySearchDirection.TO));
// cache.evict(keys);
// log.debug("Processed evict event: {}", event);
List<RelationCacheKey> keys = new ArrayList<>(2);
keys.add(RelationCacheKey.builder().from(entityId).entityProfile(profileId).build());
keys.add(RelationCacheKey.builder().to(entityId).entityProfile(profileId).build());
cache.evict(keys);
log.debug("Processed evict relations by keys: {}", keys);
}
private void validate(ProfileEntityRelationPathQuery relationPathQuery) {
validateId((UUIDBased) relationPathQuery.rootEntityId(), id -> "Invalid root entity id: " + id);
relationPathQuery.level().validate();
}
private void validate(EntityRelationPathQuery relationPathQuery) {
validateId((UUIDBased) relationPathQuery.rootEntityId(), id -> "Invalid root entity id: " + id);
List<RelationPathLevel> levels = relationPathQuery.levels();

7
dao/src/main/java/org/thingsboard/server/dao/relation/RelationCacheKey.java

@ -40,14 +40,9 @@ public class RelationCacheKey implements Serializable {
private final String type;
private final RelationTypeGroup typeGroup;
private final EntitySearchDirection direction;
private final EntityId entityProfile;
public RelationCacheKey(EntityId from, EntityId to, String type, RelationTypeGroup typeGroup) {
this(from, to, type, typeGroup, null, null);
}
public RelationCacheKey(EntityId from, EntityId to, String type, RelationTypeGroup typeGroup, EntitySearchDirection direction) {
this(from, to, type, typeGroup, direction, null);
this(from, to, type, typeGroup, null);
}
@Override

7
dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java

@ -20,7 +20,6 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationPathQuery;
import org.thingsboard.server.common.data.relation.ProfileEntityRelationPathQuery;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChainType;
@ -37,12 +36,8 @@ public interface RelationDao {
List<EntityRelation> findAllByFromAndType(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup);
List<EntityRelation> findByFromAndTypeAndProfile(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup, EntityId profileId);
List<EntityRelation> findAllByTo(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup);
List<EntityRelation> findByToAndTypeAndProfile(TenantId tenantId, EntityId to, String relationType, RelationTypeGroup typeGroup, EntityId profileId);
List<EntityRelation> findAllByTo(TenantId tenantId, EntityId to);
List<EntityRelation> findAllByToAndType(TenantId tenantId, EntityId to, String relationType, RelationTypeGroup typeGroup);
@ -79,6 +74,4 @@ public interface RelationDao {
List<EntityRelation> findByRelationPathQuery(TenantId tenantId, EntityRelationPathQuery relationPathQuery);
List<EntityRelation> findByProfileEntityRelationPathQuery(TenantId tenantId, ProfileEntityRelationPathQuery query);
}

108
dao/src/main/java/org/thingsboard/server/dao/sql/relation/JpaRelationDao.java

@ -27,7 +27,6 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationPathQuery;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.ProfileEntityRelationPathQuery;
import org.thingsboard.server.common.data.relation.RelationPathLevel;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChainType;
@ -42,12 +41,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TABLE_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TABLE_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.RELATION_FROM_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.RELATION_FROM_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.RELATION_TABLE_NAME;
@ -107,11 +103,6 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple
typeGroup.name()));
}
@Override
public List<EntityRelation> findByFromAndTypeAndProfile(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup, EntityId profileId) {
return DaoUtil.convertDataList(relationRepository.findByFromAndProfile(from.getId(), from.getEntityType().name(), typeGroup.name(), relationType, profileId.getId()));
}
@Override
public List<EntityRelation> findAllByTo(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup) {
return DaoUtil.convertDataList(
@ -121,17 +112,6 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple
typeGroup.name()));
}
@Override
public List<EntityRelation> findByToAndTypeAndProfile(TenantId tenantId, EntityId to, String relationType, RelationTypeGroup typeGroup, EntityId profileId) {
return DaoUtil.convertDataList(
relationRepository.findByToAndProfile(
to.getId(),
to.getEntityType().name(),
typeGroup.name(),
relationType,
profileId.getId()));
}
@Override
public List<EntityRelation> findAllByTo(TenantId tenantId, EntityId to) {
return DaoUtil.convertDataList(
@ -412,92 +392,4 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple
return sb.toString();
}
@Override
public List<EntityRelation> findByProfileEntityRelationPathQuery(TenantId tenantId, ProfileEntityRelationPathQuery query) {
String sql = buildProfileEntityRelationPathSql(query);
Object[] params = buildProfileEntityRelationPathParams(query);
log.trace("[{}] profile entity relation path query: {}", tenantId, sql);
return jdbcTemplate.queryForList(sql, params).stream()
.map(row -> {
var entityRelation = new EntityRelation();
var fromId = (UUID) row.get(RELATION_FROM_ID_PROPERTY);
var fromType = (String) row.get(RELATION_FROM_TYPE_PROPERTY);
var toId = (UUID) row.get(RELATION_TO_ID_PROPERTY);
var toType = (String) row.get(RELATION_TO_TYPE_PROPERTY);
var grp = (String) row.get(RELATION_TYPE_GROUP_PROPERTY);
var type = (String) row.get(RELATION_TYPE_PROPERTY);
var version = (Long) row.get(VERSION_COLUMN);
entityRelation.setFrom(EntityIdFactory.getByTypeAndUuid(fromType, fromId));
entityRelation.setTo(EntityIdFactory.getByTypeAndUuid(toType, toId));
entityRelation.setType(type);
entityRelation.setTypeGroup(RelationTypeGroup.valueOf(grp));
entityRelation.setVersion(version);
return entityRelation;
})
.collect(Collectors.toList());
}
private Object[] buildProfileEntityRelationPathParams(ProfileEntityRelationPathQuery query) {
final List<Object> params = new ArrayList<>();
params.add(query.rootEntityId().getId());
params.add(query.rootEntityId().getEntityType().name());
params.add(query.level().relationType());
if (query.targetEntityProfileId() != null) {
params.add(query.targetEntityProfileId().getId());
params.add(query.targetEntityProfileId().getId());
}
return params.toArray();
}
private static String buildProfileEntityRelationPathSql(ProfileEntityRelationPathQuery query) {
EntitySearchDirection direction = query.level().direction();
StringBuilder sb = new StringBuilder();
sb.append("\n")
.append("SELECT r.from_id, r.from_type, r.to_id, r.to_type,\n")
.append(" r.relation_type_group, r.relation_type, r.version\n")
.append("FROM ").append(RELATION_TABLE_NAME).append(" r\n");
sb.append("JOIN ").append(DEVICE_TABLE_NAME).append(" d ON ");
if (EntitySearchDirection.FROM == direction) {
sb.append("r.to_id = d.id AND r.to_type = 'DEVICE'").append("\n");
} else {
sb.append("r.from_id = d.id AND r.from_type = 'DEVICE'").append("\n");
}
sb.append("JOIN ").append(ASSET_TABLE_NAME).append(" a ON ");
if (EntitySearchDirection.FROM == direction) {
sb.append("r.to_id = a.id AND r.to_type = 'ASSET'").append("\n");
} else {
sb.append("r.from_id = a.id AND r.from_type = 'ASSET'").append("\n");
}
if (EntitySearchDirection.FROM == direction) {
sb.append("WHERE r.from_id = ?").append("\n")
.append("AND r.from_type = ?").append("\n");
} else {
sb.append("WHERE r.to_id = ?").append("\n")
.append("AND r.to_type = ?").append("\n");
}
sb.append("AND r.relation_type = ?").append("\n")
.append("AND r.relation_type_group = '").append(RelationTypeGroup.COMMON).append("'\n");
if (query.targetEntityProfileId() != null) {
sb.append("AND ((d.device_profile_id = ?) OR (a.asset_profile_id = ?))").append("\n");
}
sb.append("AND (d.id IS NOT NULL OR a.id IS NOT NULL)");
return sb.toString();
}
}

36
dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java

@ -27,7 +27,6 @@ import org.thingsboard.server.dao.model.sql.RelationCompositeKey;
import org.thingsboard.server.dao.model.sql.RelationEntity;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface RelationRepository
@ -97,39 +96,4 @@ public interface RelationRepository
@Param("toType") String toType,
@Param("batchSize") int batchSize);
@Query(value = """
SELECT r.from_id, r.from_type, r.relation_type_group, r.relation_type, r.to_id, r.to_type, r.additional_info, r.version
FROM relation r
LEFT JOIN device d ON r.to_id = d.id AND r.to_type = 'DEVICE'
LEFT JOIN asset a ON r.to_id = a.id AND r.to_type = 'ASSET'
WHERE r.from_id = :fromId
AND r.from_type = :fromType
AND r.relation_type = :relationType
AND r.relation_type_group = :relationTypeGroup
AND ((d.device_profile_id = :profileId) OR (a.asset_profile_id = :profileId))
AND (d.id IS NOT NULL OR a.id IS NOT NULL)
""", nativeQuery = true)
List<RelationEntity> findByFromAndProfile(@Param("fromId") UUID fromId,
@Param("fromType") String fromType,
@Param("relationTypeGroup") String relationTypeGroup,
@Param("relationType") String relationType,
@Param("profileId") UUID profileId);
@Query(value = """
SELECT r.from_id, r.from_type, r.relation_type_group, r.relation_type, r.to_id, r.to_type, r.additional_info, r.version
FROM relation r
LEFT JOIN device d ON r.from_id = d.id AND r.from_type = 'DEVICE'
LEFT JOIN asset a ON r.from_id = a.id AND r.from_type = 'ASSET'
WHERE r.to_id = :toId
AND r.to_type = :toType
AND r.relation_type = :relationType
AND r.relation_type_group = :relationTypeGroup
AND ((d.device_profile_id = :profileId) OR (a.asset_profile_id = :profileId))
AND (d.id IS NOT NULL OR a.id IS NOT NULL)
""", nativeQuery = true)
List<RelationEntity> findByToAndProfile(@Param("toId") UUID toId,
@Param("toType") String toType,
@Param("relationTypeGroup") String relationTypeGroup,
@Param("relationType") String relationType,
@Param("profileId") UUID profileId);
}

Loading…
Cancel
Save