Entities version refactoring

This commit is contained in:
ViacheslavKlimov 2024-07-05 16:20:19 +03:00
parent 7fb5f268c7
commit 1dcb64d298
34 changed files with 100 additions and 113 deletions

View File

@ -1587,18 +1587,24 @@ public class DeviceControllerTest extends AbstractControllerTest {
@Test
public void testSaveDeviceWithOutdatedVersion() throws Exception {
Device device = createDevice("Device v1");
Device device = createDevice("Device v1.0");
assertThat(device.getVersion()).isOne();
device.setName("Device v2");
device.setName("Device v2.0");
device = doPost("/api/device", device, Device.class);
assertThat(device.getVersion()).isEqualTo(2);
device.setVersion(1);
device.setName("Device v1.1");
device.setVersion(1L);
String response = doPost("/api/device", device).andExpect(status().isConflict())
.andReturn().getResponse().getContentAsString();
assertThat(JacksonUtil.toJsonNode(response).get("message").asText())
.containsIgnoringCase("already changed by someone else");
device.setVersion(null); // overriding entity
device = doPost("/api/device", device, Device.class);
assertThat(device.getName()).isEqualTo("Device v1.1");
assertThat(device.getVersion()).isEqualTo(3);
}
private Device createDevice(String name) {

View File

@ -44,7 +44,7 @@ public class Customer extends ContactBased<CustomerId> implements HasTenantId, E
@Getter @Setter
private CustomerId externalId;
@Getter @Setter
private Integer version;
private Long version;
public Customer() {
super();

View File

@ -46,7 +46,7 @@ public class DashboardInfo extends BaseData<DashboardId> implements HasName, Has
private Integer mobileOrder;
@Getter @Setter
private Integer version;
private Long version;
public DashboardInfo() {
super();

View File

@ -68,7 +68,7 @@ public class Device extends BaseDataWithAdditionalInfo<DeviceId> implements HasL
@Getter @Setter
private DeviceId externalId;
@Getter @Setter
private Integer version;
private Long version;
public Device() {
super();

View File

@ -97,7 +97,7 @@ public class DeviceProfile extends BaseData<DeviceProfileId> implements HasName,
private RuleChainId defaultEdgeRuleChainId;
private DeviceProfileId externalId;
private Integer version;
private Long version;
public DeviceProfile() {
super();

View File

@ -60,7 +60,7 @@ public class EntityView extends BaseDataWithAdditionalInfo<EntityViewId>
private long endTimeMs;
private EntityViewId externalId;
private Integer version;
private Long version;
public EntityView() {
super();

View File

@ -19,6 +19,7 @@ public interface HasVersion {
Long getVersion();
void setVersion(Integer version);
default void setVersion(Long version) {
}
}

View File

@ -53,7 +53,7 @@ public class User extends BaseDataWithAdditionalInfo<UserId> implements HasName,
private String phone;
@Getter @Setter
private Integer version;
private Long version;
public User() {
super();

View File

@ -58,7 +58,7 @@ public class Asset extends BaseDataWithAdditionalInfo<AssetId> implements HasLab
@Getter @Setter
private AssetId externalId;
@Getter @Setter
private Integer version;
private Long version;
public Asset() {
super();

View File

@ -75,7 +75,7 @@ public class AssetProfile extends BaseData<AssetProfileId> implements HasName, H
private RuleChainId defaultEdgeRuleChainId;
private AssetProfileId externalId;
private Integer version;
private Long version;
public AssetProfile() {
super();

View File

@ -60,7 +60,7 @@ public class Edge extends BaseDataWithAdditionalInfo<EdgeId> implements HasLabel
private String secret;
@Getter
private Integer version;
private Long version;
public Edge() {
super();

View File

@ -59,7 +59,7 @@ public class RuleChain extends BaseDataWithAdditionalInfo<RuleChainId> implement
private transient JsonNode configuration;
private RuleChainId externalId;
private Integer version;
private Long version;
@JsonIgnore
private byte[] configurationBytes;

View File

@ -35,7 +35,7 @@ public class DeviceCredentials extends BaseData<DeviceCredentialsId> implements
private String credentialsValue;
@Getter @Setter
private Integer version;
private Long version;
public DeviceCredentials() {
super();

View File

@ -47,7 +47,7 @@ public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasName, H
@Schema(description = "Whether widget type is deprecated.", example = "true")
private boolean deprecated;
private Integer version;
private Long version;
public BaseWidgetType() {
super();

View File

@ -79,7 +79,7 @@ public class WidgetsBundle extends BaseData<WidgetsBundleId> implements HasName,
private WidgetsBundleId externalId;
@Getter
@Setter
private Integer version;
private Long version;
public WidgetsBundle() {
super();

View File

@ -209,7 +209,7 @@ message DeviceProto {
optional int64 softwareIdLSB = 18;
optional int64 externalIdMSB = 19;
optional int64 externalIdLSB = 20;
optional int32 version = 21;
optional int64 version = 21;
}
message DeviceProfileProto {
@ -240,7 +240,7 @@ message DeviceProfileProto {
optional int64 defaultEdgeRuleChainIdLSB = 25;
optional int64 externalIdMSB = 26;
optional int64 externalIdLSB = 27;
optional int32 version = 28;
optional int64 version = 28;
}
message TenantProto {
@ -670,7 +670,7 @@ message DeviceCredentialsProto {
CredentialsType credentialsType = 6;
string credentialsId = 7;
optional string credentialsValue = 8;
optional int32 version = 9;
optional int64 version = 9;
}
message CredentialsDataProto {

View File

@ -15,6 +15,47 @@
*/
package org.thingsboard.server.dao.model;
public interface BaseVersionedEntity {
long getVersion();
import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Version;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.HasVersion;
@Data
@EqualsAndHashCode(callSuper = true)
@MappedSuperclass
public abstract class BaseVersionedEntity<D extends BaseData & HasVersion> extends BaseSqlEntity<D> implements HasVersion {
@Getter @Setter
@Version
@Column(name = ModelConstants.VERSION_PROPERTY)
protected Long version;
public BaseVersionedEntity() {
super();
}
public BaseVersionedEntity(D domain) {
super(domain);
this.version = domain.getVersion();
}
public BaseVersionedEntity(BaseVersionedEntity<?> entity) {
super(entity);
this.version = entity.version;
}
@Override
public String toString() {
return "BaseVersionedEntity{" +
"id=" + id +
", createdTime=" + createdTime +
", version=" + version +
'}';
}
}

View File

@ -1,61 +0,0 @@
/**
* Copyright © 2016-2024 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.dao.model;
import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Version;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.HasVersion;
@Data
@EqualsAndHashCode(callSuper = true)
@MappedSuperclass
public abstract class BaseVersionedSqlEntity<D extends BaseData & HasVersion> extends BaseSqlEntity<D> implements HasVersion {
@Getter @Setter
@Version
@Column(name = ModelConstants.VERSION_PROPERTY)
protected Integer version;
public BaseVersionedSqlEntity() {
super();
}
public BaseVersionedSqlEntity(D domain) {
super(domain);
this.version = domain.getVersion();
}
public BaseVersionedSqlEntity(BaseVersionedSqlEntity<?> entity) {
super(entity);
this.version = entity.version;
}
@Override
public String toString() {
return "BaseVersionedSqlEntity{" +
"id=" + id +
", createdTime=" + createdTime +
", version=" + version +
'}';
}
}

View File

@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.AssetProfileId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonConverter;
@ -42,7 +42,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.EXTERNAL_ID_PROPER
@Data
@EqualsAndHashCode(callSuper = true)
@MappedSuperclass
public abstract class AbstractAssetEntity<T extends Asset> extends BaseVersionedSqlEntity<T> {
public abstract class AbstractAssetEntity<T extends Asset> extends BaseVersionedEntity<T> {
@Column(name = ASSET_TENANT_ID_PROPERTY)
private UUID tenantId;

View File

@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonConverter;
@ -41,7 +41,7 @@ import java.util.UUID;
@Data
@EqualsAndHashCode(callSuper = true)
@MappedSuperclass
public abstract class AbstractDeviceEntity<T extends Device> extends BaseVersionedSqlEntity<T> {
public abstract class AbstractDeviceEntity<T extends Device> extends BaseVersionedEntity<T> {
@Column(name = ModelConstants.DEVICE_TENANT_ID_PROPERTY, columnDefinition = "uuid")
private UUID tenantId;

View File

@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonConverter;
@ -44,7 +44,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TYPE_PROPERTY
@Data
@EqualsAndHashCode(callSuper = true)
@MappedSuperclass
public abstract class AbstractEdgeEntity<T extends Edge> extends BaseVersionedSqlEntity<T> {
public abstract class AbstractEdgeEntity<T extends Edge> extends BaseVersionedEntity<T> {
@Column(name = EDGE_TENANT_ID_PROPERTY, columnDefinition = "uuid")
private UUID tenantId;

View File

@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.objects.TelemetryEntityView;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonConverter;
@ -48,7 +48,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_TYPE_PROPER
@EqualsAndHashCode(callSuper = true)
@MappedSuperclass
@Slf4j
public abstract class AbstractEntityViewEntity<T extends EntityView> extends BaseVersionedSqlEntity<T> {
public abstract class AbstractEntityViewEntity<T extends EntityView> extends BaseVersionedEntity<T> {
@Column(name = ModelConstants.ENTITY_VIEW_ENTITY_ID_PROPERTY)
private UUID entityId;

View File

@ -22,7 +22,7 @@ import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.widget.BaseWidgetType;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import java.util.UUID;
@ -30,7 +30,7 @@ import java.util.UUID;
@Data
@EqualsAndHashCode(callSuper = true)
@MappedSuperclass
public abstract class AbstractWidgetTypeEntity<T extends BaseWidgetType> extends BaseVersionedSqlEntity<T> {
public abstract class AbstractWidgetTypeEntity<T extends BaseWidgetType> extends BaseVersionedEntity<T> {
@Column(name = ModelConstants.WIDGET_TYPE_TENANT_ID_PROPERTY)
private UUID tenantId;

View File

@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.id.AssetProfileId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import java.util.UUID;
@ -34,7 +34,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.ASSET_PROFILE_TABLE_NAME)
public final class AssetProfileEntity extends BaseVersionedSqlEntity<AssetProfile> {
public final class AssetProfileEntity extends BaseVersionedEntity<AssetProfile> {
@Column(name = ModelConstants.ASSET_PROFILE_TENANT_ID_PROPERTY)
private UUID tenantId;

View File

@ -25,8 +25,7 @@ import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonConverter;
@ -36,7 +35,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.CUSTOMER_TABLE_NAME)
public final class CustomerEntity extends BaseVersionedSqlEntity<Customer> {
public final class CustomerEntity extends BaseVersionedEntity<Customer> {
@Column(name = ModelConstants.CUSTOMER_TENANT_ID_PROPERTY)
private UUID tenantId;

View File

@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.ShortCustomerInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonConverter;
@ -42,7 +42,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.DASHBOARD_TABLE_NAME)
public final class DashboardEntity extends BaseVersionedSqlEntity<Dashboard> {
public final class DashboardEntity extends BaseVersionedEntity<Dashboard> {
private static final JavaType assignedCustomersType =
JacksonUtil.constructCollectionType(HashSet.class, ShortCustomerInfo.class);

View File

@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.ShortCustomerInfo;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import java.util.HashSet;
@ -39,7 +39,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.DASHBOARD_TABLE_NAME)
public class DashboardInfoEntity extends BaseVersionedSqlEntity<DashboardInfo> {
public class DashboardInfoEntity extends BaseVersionedEntity<DashboardInfo> {
private static final JavaType assignedCustomersType =
JacksonUtil.constructCollectionType(HashSet.class, ShortCustomerInfo.class);

View File

@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.id.DeviceCredentialsId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import java.util.UUID;
@ -35,7 +35,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.DEVICE_CREDENTIALS_TABLE_NAME)
public final class DeviceCredentialsEntity extends BaseVersionedSqlEntity<DeviceCredentials> {
public final class DeviceCredentialsEntity extends BaseVersionedEntity<DeviceCredentials> {
@Column(name = ModelConstants.DEVICE_CREDENTIALS_DEVICE_ID_PROPERTY)
private UUID deviceId;

View File

@ -38,7 +38,7 @@ import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.OtaPackageId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonConverter;
@ -48,7 +48,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.DEVICE_PROFILE_TABLE_NAME)
public final class DeviceProfileEntity extends BaseVersionedSqlEntity<DeviceProfile> {
public final class DeviceProfileEntity extends BaseVersionedEntity<DeviceProfile> {
@Column(name = ModelConstants.DEVICE_PROFILE_TENANT_ID_PROPERTY)
private UUID tenantId;

View File

@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainType;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonConverter;
@ -40,7 +40,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.RULE_CHAIN_TABLE_NAME)
public class RuleChainEntity extends BaseVersionedSqlEntity<RuleChain> {
public class RuleChainEntity extends BaseVersionedEntity<RuleChain> {
@Column(name = ModelConstants.RULE_CHAIN_TENANT_ID_PROPERTY)
private UUID tenantId;

View File

@ -29,7 +29,7 @@ import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.util.mapping.JsonConverter;
@ -42,7 +42,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.USER_PG_HIBERNATE_TABLE_NAME)
public class UserEntity extends BaseVersionedSqlEntity<User> {
public class UserEntity extends BaseVersionedEntity<User> {
@Column(name = ModelConstants.USER_TENANT_ID_PROPERTY)
private UUID tenantId;

View File

@ -27,4 +27,5 @@ public abstract class VersionedEntity {
@Column(name = VERSION_COLUMN)
protected Long version;
}

View File

@ -24,7 +24,7 @@ import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.model.BaseVersionedSqlEntity;
import org.thingsboard.server.dao.model.BaseVersionedEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import java.util.UUID;
@ -33,7 +33,7 @@ import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = ModelConstants.WIDGETS_BUNDLE_TABLE_NAME)
public final class WidgetsBundleEntity extends BaseVersionedSqlEntity<WidgetsBundle> {
public final class WidgetsBundleEntity extends BaseVersionedEntity<WidgetsBundle> {
@Column(name = ModelConstants.WIDGETS_BUNDLE_TENANT_ID_PROPERTY)
private UUID tenantId;

View File

@ -87,7 +87,7 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D>
protected E doSave(E entity, boolean isNew) {
if (isNew) {
if (entity instanceof HasVersion versionedEntity) {
versionedEntity.setVersion(1);
versionedEntity.setVersion(1L);
}
entityManager.persist(entity);
} else {