diff --git a/dao/pom.xml b/dao/pom.xml
index d95521ddd0..ced5c381f4 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -173,11 +173,6 @@
spring-test
test
-
- org.springframework
- spring-test
- compile
-
com.h2database
h2
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java
index 25393fb971..27f988a780 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java
@@ -25,9 +25,12 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.id.AdminSettingsId;
import org.thingsboard.server.dao.model.BaseEntity;
+import org.thingsboard.server.dao.util.JsonBinaryType;
import java.io.IOException;
import java.util.UUID;
@@ -35,8 +38,8 @@ import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.*;
@Data
-@Slf4j
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ADMIN_SETTINGS_COLUMN_FAMILY_NAME)
public final class AdminSettingsEntity implements BaseEntity {
@@ -50,8 +53,9 @@ public final class AdminSettingsEntity implements BaseEntity {
@Column(name = ADMIN_SETTINGS_KEY_PROPERTY)
private String key;
- @Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY)
- private String jsonValue;
+ @Type(type = "jsonb")
+ @Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode jsonValue;
public AdminSettingsEntity() {
super();
@@ -62,9 +66,7 @@ public final class AdminSettingsEntity implements BaseEntity {
this.id = adminSettings.getId().getId();
}
this.key = adminSettings.getKey();
- if (jsonValue != null) {
- this.jsonValue = adminSettings.getJsonValue().toString();
- }
+ this.jsonValue = adminSettings.getJsonValue();
}
@Override
@@ -132,16 +134,7 @@ public final class AdminSettingsEntity implements BaseEntity {
AdminSettings adminSettings = new AdminSettings(new AdminSettingsId(id));
adminSettings.setCreatedTime(UUIDs.unixTimestamp(id));
adminSettings.setKey(key);
- if (jsonValue != null) {
- ObjectMapper mapper = new ObjectMapper();
- JsonNode jsonNode = null;
- try {
- jsonNode = mapper.readTree(jsonValue);
- adminSettings.setJsonValue(jsonNode);
- } catch (IOException e) {
- log.error(e.getMessage(), e);
- }
- }
+ adminSettings.setJsonValue(jsonValue);
return adminSettings;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java
index 37fab4f487..02cad5d8e6 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java
@@ -24,19 +24,22 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.ComponentDescriptorId;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentScope;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
+import org.thingsboard.server.dao.util.JsonBinaryType;
import java.io.IOException;
import java.util.UUID;
@Data
-@Slf4j
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME)
public class ComponentDescriptorEntity implements SearchTextEntity {
@@ -59,8 +62,9 @@ public class ComponentDescriptorEntity implements SearchTextEntity {
@@ -80,8 +80,9 @@ public final class CustomerEntity implements SearchTextEntity {
@Column(name = ModelConstants.EMAIL_PROPERTY)
private String email;
- @Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY)
- private String additionalInfo;
+ @Type(type = "jsonb")
+ @Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode additionalInfo;
public CustomerEntity() {
super();
@@ -101,9 +102,7 @@ public final class CustomerEntity implements SearchTextEntity {
this.zip = customer.getZip();
this.phone = customer.getPhone();
this.email = customer.getEmail();
- if (additionalInfo != null) {
- this.additionalInfo = customer.getAdditionalInfo().toString();
- }
+ this.additionalInfo = customer.getAdditionalInfo();
}
@Override
@@ -262,15 +261,7 @@ public final class CustomerEntity implements SearchTextEntity {
customer.setZip(zip);
customer.setPhone(phone);
customer.setEmail(email);
- if (additionalInfo != null) {
- ObjectMapper mapper = new ObjectMapper();
- try {
- JsonNode jsonNode = mapper.readTree(additionalInfo);
- customer.setAdditionalInfo(jsonNode);
- } catch (IOException e) {
- log.error(e.getMessage(), e);
- }
- }
+ customer.setAdditionalInfo(additionalInfo);
return customer;
}
}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java
index 1ad0f84633..4cc46f466c 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java
@@ -25,19 +25,22 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
+import org.thingsboard.server.dao.util.JsonBinaryType;
import java.io.IOException;
import java.util.UUID;
@Data
-@Slf4j
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME)
public final class DashboardEntity implements SearchTextEntity {
@@ -59,9 +62,10 @@ public final class DashboardEntity implements SearchTextEntity {
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
-
- @Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY)
- private String configuration;
+
+ @Type(type = "jsonb")
+ @Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode configuration;
public DashboardEntity() {
super();
@@ -78,9 +82,7 @@ public final class DashboardEntity implements SearchTextEntity {
this.customerId = dashboard.getCustomerId().getId();
}
this.title = dashboard.getTitle();
- if (configuration != null) {
- this.configuration = dashboard.getConfiguration().toString();
- }
+ this.configuration = dashboard.getConfiguration();
}
@Override
@@ -191,16 +193,7 @@ public final class DashboardEntity implements SearchTextEntity {
dashboard.setCustomerId(new CustomerId(customerId));
}
dashboard.setTitle(title);
- if (configuration != null) {
- ObjectMapper mapper = new ObjectMapper();
- JsonNode jsonNode = null;
- try {
- jsonNode = mapper.readTree(configuration);
- dashboard.setConfiguration(jsonNode);
- } catch (IOException e) {
- log.error(e.getMessage(), e);
- }
- }
+ dashboard.setConfiguration(configuration);
return dashboard;
}
}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
index 0b1ecdf40c..0504ccf903 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
@@ -25,19 +25,22 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
+import org.thingsboard.server.dao.util.JsonBinaryType;
import java.io.IOException;
import java.util.UUID;
@Data
-@Slf4j
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.DEVICE_COLUMN_FAMILY_NAME)
public final class DeviceEntity implements SearchTextEntity {
@@ -59,9 +62,10 @@ public final class DeviceEntity implements SearchTextEntity {
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
-
- @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY)
- private String additionalInfo;
+
+ @Type(type = "jsonb")
+ @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode additionalInfo;
public DeviceEntity() {
super();
@@ -78,9 +82,7 @@ public final class DeviceEntity implements SearchTextEntity {
this.customerId = device.getCustomerId().getId();
}
this.name = device.getName();
- if (additionalInfo != null) {
- this.additionalInfo = device.getAdditionalInfo().toString();
- }
+ this.additionalInfo = device.getAdditionalInfo();
}
@Override
@@ -174,16 +176,7 @@ public final class DeviceEntity implements SearchTextEntity {
device.setCustomerId(new CustomerId(customerId));
}
device.setName(name);
- if (additionalInfo != null) {
- ObjectMapper mapper = new ObjectMapper();
- JsonNode jsonNode = null;
- try {
- jsonNode = mapper.readTree(additionalInfo);
- device.setAdditionalInfo(jsonNode);
- } catch (IOException e) {
- log.error(e.getMessage(), e);
- }
- }
+ device.setAdditionalInfo(additionalInfo);
return device;
}
}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
index a0cce5ca22..65e51a0879 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
@@ -26,10 +26,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Event;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.dao.model.BaseEntity;
+import org.thingsboard.server.dao.util.JsonBinaryType;
import static org.thingsboard.server.dao.model.ModelConstants.*;
@@ -37,9 +40,9 @@ import java.io.IOException;
import java.util.UUID;
@Data
-@Slf4j
@NoArgsConstructor
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = EVENT_COLUMN_FAMILY_NAME)
public class EventEntity implements BaseEntity {
@@ -65,8 +68,9 @@ public class EventEntity implements BaseEntity {
@Column(name = EVENT_UID_PROPERTY)
private String eventUid;
- @Column(name = EVENT_BODY_PROPERTY)
- private String body;
+ @Type(type = "jsonb")
+ @Column(name = EVENT_BODY_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode body;
public EventEntity(Event event) {
if (event.getId() != null) {
@@ -81,9 +85,7 @@ public class EventEntity implements BaseEntity {
}
this.eventType = event.getType();
this.eventUid = event.getUid();
- if (event.getBody() != null) {
- this.body = event.getBody().toString();
- }
+ this.body = event.getBody();
}
@Override
@@ -118,15 +120,7 @@ public class EventEntity implements BaseEntity {
event.setEntityId(new PluginId(entityId));
break;
}
- ObjectMapper mapper = new ObjectMapper();
- if (body != null) {
- try {
- JsonNode jsonNode = mapper.readTree(body);
- event.setBody(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", body, e.getMessage()), e);
- }
- }
+ event.setBody(body);
event.setType(eventType);
event.setUid(eventUid);
return event;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java
index 1e5d1b09a1..8d8974dcf8 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java
@@ -25,19 +25,23 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.PluginId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
+import org.thingsboard.server.dao.util.JsonBinaryType;
import java.io.IOException;
import java.util.Objects;
import java.util.UUID;
-@Slf4j
+
@Data
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.PLUGIN_COLUMN_FAMILY_NAME)
public class PluginMetaDataEntity implements SearchTextEntity {
@@ -65,15 +69,17 @@ public class PluginMetaDataEntity implements SearchTextEntity {
@Column(name = ModelConstants.PLUGIN_STATE_PROPERTY)
private ComponentLifecycleState state;
- @Column(name = ModelConstants.PLUGIN_CONFIGURATION_PROPERTY)
- private String configuration;
+ @Type(type = "jsonb")
+ @Column(name = ModelConstants.PLUGIN_CONFIGURATION_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode configuration;
+
+ @Type(type = "jsonb")
+ @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode additionalInfo;
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
- @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY)
- private String additionalInfo;
-
public PluginMetaDataEntity() {
}
@@ -88,12 +94,8 @@ public class PluginMetaDataEntity implements SearchTextEntity {
this.publicAccess = pluginMetaData.isPublicAccess();
this.state = pluginMetaData.getState();
this.searchText = pluginMetaData.getName();
- if (pluginMetaData.getConfiguration() != null) {
- this.configuration = pluginMetaData.getConfiguration().toString();
- }
- if (pluginMetaData.getAdditionalInfo() != null) {
- this.additionalInfo = pluginMetaData.getAdditionalInfo().toString();
- }
+ this.configuration = pluginMetaData.getConfiguration();
+ this.additionalInfo = pluginMetaData.getAdditionalInfo();
}
@Override
@@ -126,23 +128,8 @@ public class PluginMetaDataEntity implements SearchTextEntity {
data.setPublicAccess(publicAccess);
data.setState(state);
data.setApiToken(apiToken);
- ObjectMapper mapper = new ObjectMapper();
- if (configuration != null) {
- try {
- JsonNode jsonNode = mapper.readTree(configuration);
- data.setConfiguration(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", configuration, e.getMessage()), e);
- }
- }
- if (additionalInfo != null) {
- try {
- JsonNode jsonNode = mapper.readTree(additionalInfo);
- data.setAdditionalInfo(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
- }
- }
+ data.setConfiguration(configuration);
+ data.setAdditionalInfo(additionalInfo);
return data;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java
index 54359a35aa..193501a981 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java
@@ -27,6 +27,8 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.RuleId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
@@ -34,14 +36,15 @@ import org.thingsboard.server.common.data.rule.RuleMetaData;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
+import org.thingsboard.server.dao.util.JsonBinaryType;
import java.io.IOException;
import java.util.Objects;
import java.util.UUID;
-@Slf4j
@Data
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.RULE_COLUMN_FAMILY_NAME)
public class RuleMetaDataEntity implements SearchTextEntity {
@@ -62,14 +65,18 @@ public class RuleMetaDataEntity implements SearchTextEntity {
private String searchText;
@Column(name = ModelConstants.RULE_PLUGIN_TOKEN_PROPERTY)
private String pluginToken;
- @Column(name = ModelConstants.RULE_FILTERS)
- private String filters;
- @Column(name = ModelConstants.RULE_PROCESSOR)
- private String processor;
- @Column(name = ModelConstants.RULE_ACTION)
- private String action;
- @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY)
- private String additionalInfo;
+ @Type(type = "jsonb")
+ @Column(name = ModelConstants.RULE_FILTERS, columnDefinition = "jsonb")
+ private JsonNode filters;
+ @Type(type = "jsonb")
+ @Column(name = ModelConstants.RULE_PROCESSOR, columnDefinition = "jsonb")
+ private JsonNode processor;
+ @Type(type = "jsonb")
+ @Column(name = ModelConstants.RULE_ACTION, columnDefinition = "jsonb")
+ private JsonNode action;
+ @Type(type = "jsonb")
+ @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode additionalInfo;
public RuleMetaDataEntity() {
}
@@ -84,18 +91,10 @@ public class RuleMetaDataEntity implements SearchTextEntity {
this.state = rule.getState();
this.weight = rule.getWeight();
this.searchText = rule.getName();
- if (rule.getFilters() != null) {
- this.filters = rule.getFilters().toString();
- }
- if (rule.getProcessor() != null) {
- this.processor = rule.getProcessor().toString();
- }
- if (rule.getAction() != null) {
- this.action = rule.getAction().toString();
- }
- if (rule.getAdditionalInfo() != null) {
- this.additionalInfo = rule.getAdditionalInfo().toString();
- }
+ this.filters = rule.getFilters();
+ this.processor = rule.getProcessor();
+ this.action = rule.getAction();
+ this.additionalInfo = rule.getAdditionalInfo();
}
@Override
@@ -127,39 +126,10 @@ public class RuleMetaDataEntity implements SearchTextEntity {
rule.setWeight(weight);
rule.setCreatedTime(UUIDs.unixTimestamp(id));
rule.setPluginToken(pluginToken);
- ObjectMapper mapper = new ObjectMapper();
- if (filters != null) {
- try {
- JsonNode jsonNode = mapper.readTree(filters);
- rule.setFilters(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", filters, e.getMessage()), e);
- }
- }
- if (processor != null) {
- try {
- JsonNode jsonNode = mapper.readTree(processor);
- rule.setProcessor(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", processor, e.getMessage()), e);
- }
- }
- if (action != null) {
- try {
- JsonNode jsonNode = mapper.readTree(action);
- rule.setAction(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", action, e.getMessage()), e);
- }
- }
- if (additionalInfo != null) {
- try {
- JsonNode jsonNode = mapper.readTree(additionalInfo);
- rule.setAdditionalInfo(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
- }
- }
+ rule.setFilters(filters);
+ rule.setProcessor(processor);
+ rule.setAction(action);
+ rule.setAdditionalInfo(additionalInfo);
return rule;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
index 6a2e8a066b..fcd5b19f63 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
@@ -26,18 +26,21 @@ import javax.persistence.Transient;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import com.fasterxml.jackson.databind.JsonNode;
+import org.thingsboard.server.dao.util.JsonBinaryType;
import java.io.IOException;
import java.util.UUID;
-@Slf4j
@Data
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.TENANT_COLUMN_FAMILY_NAME)
public final class TenantEntity implements SearchTextEntity {
@@ -81,8 +84,9 @@ public final class TenantEntity implements SearchTextEntity {
@Column(name = ModelConstants.EMAIL_PROPERTY)
private String email;
- @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY)
- private String additionalInfo;
+ @Type(type="jsonb")
+ @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode additionalInfo;
public TenantEntity() {
super();
@@ -102,12 +106,9 @@ public final class TenantEntity implements SearchTextEntity {
this.zip = tenant.getZip();
this.phone = tenant.getPhone();
this.email = tenant.getEmail();
- if (tenant.getAdditionalInfo() != null) {
- this.additionalInfo = tenant.getAdditionalInfo().toString();
- }
+ this.additionalInfo = tenant.getAdditionalInfo();
}
-
@Override
public String getSearchTextSource() {
return title;
@@ -258,15 +259,7 @@ public final class TenantEntity implements SearchTextEntity {
tenant.setZip(zip);
tenant.setPhone(phone);
tenant.setEmail(email);
- ObjectMapper mapper = new ObjectMapper();
- if (additionalInfo != null) {
- try {
- JsonNode jsonNode = mapper.readTree(additionalInfo);
- tenant.setAdditionalInfo(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
- }
- }
+ tenant.setAdditionalInfo(additionalInfo);
return tenant;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java
index c85b2aa9d9..6572462df0 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java
@@ -20,6 +20,8 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
@@ -27,6 +29,7 @@ import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
+import org.thingsboard.server.dao.util.JsonBinaryType;
import javax.persistence.*;
import java.io.IOException;
@@ -35,9 +38,9 @@ import java.util.UUID;
/**
* Created by Valerii Sosliuk on 4/21/2017.
*/
-@Slf4j
@Data
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.USER_PG_HIBERNATE_COLUMN_FAMILY_NAME)
public class UserEntity implements SearchTextEntity {
@Transient
@@ -68,8 +71,9 @@ public class UserEntity implements SearchTextEntity {
@Column(name = ModelConstants.USER_LAST_NAME_PROPERTY)
private String lastName;
- @Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY)
- private String additionalInfo;
+ @Type(type="jsonb")
+ @Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode additionalInfo;
public UserEntity() {
}
@@ -88,9 +92,7 @@ public class UserEntity implements SearchTextEntity {
this.email = user.getEmail();
this.firstName = user.getFirstName();
this.lastName = user.getLastName();
- if (user.getAdditionalInfo() != null) {
- this.additionalInfo = user.getAdditionalInfo().toString();
- }
+ this.additionalInfo = user.getAdditionalInfo();
}
@Override
@@ -150,15 +152,7 @@ public class UserEntity implements SearchTextEntity {
user.setEmail(email);
user.setFirstName(firstName);
user.setLastName(lastName);
- ObjectMapper mapper = new ObjectMapper();
- if (additionalInfo != null) {
- try {
- JsonNode jsonNode = mapper.readTree(additionalInfo);
- user.setAdditionalInfo(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", additionalInfo, e.getMessage()), e);
- }
- }
+ user.setAdditionalInfo(additionalInfo);
return user;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java
index 4f31e70201..28de47ffc6 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java
@@ -16,29 +16,24 @@
package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
import com.datastax.driver.mapping.annotations.PartitionKey;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
-import lombok.extern.slf4j.Slf4j;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.dao.model.BaseEntity;
import org.thingsboard.server.dao.model.ModelConstants;
+import org.thingsboard.server.dao.util.JsonBinaryType;
-import java.io.IOException;
+import javax.persistence.*;
import java.util.UUID;
-@Slf4j
@Data
@Entity
+@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME)
public final class WidgetTypeEntity implements BaseEntity {
@@ -63,8 +58,9 @@ public final class WidgetTypeEntity implements BaseEntity {
@Column(name = ModelConstants.WIDGET_TYPE_NAME_PROPERTY)
private String name;
- @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY)
- private String descriptor;
+ @Type(type="jsonb")
+ @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY, columnDefinition = "jsonb")
+ private JsonNode descriptor;
public WidgetTypeEntity() {
super();
@@ -80,9 +76,7 @@ public final class WidgetTypeEntity implements BaseEntity {
this.bundleAlias = widgetType.getBundleAlias();
this.alias = widgetType.getAlias();
this.name = widgetType.getName();
- if (widgetType.getDescriptor() != null) {
- this.descriptor = widgetType.getDescriptor().toString();
- }
+ this.descriptor = widgetType.getDescriptor();
}
@Override
@@ -144,15 +138,7 @@ public final class WidgetTypeEntity implements BaseEntity {
widgetType.setBundleAlias(bundleAlias);
widgetType.setAlias(alias);
widgetType.setName(name);
- ObjectMapper mapper = new ObjectMapper();
- if (descriptor != null) {
- try {
- JsonNode jsonNode = mapper.readTree(descriptor);
- widgetType.setDescriptor(jsonNode);
- } catch (IOException e) {
- log.warn(String.format("Error parsing JsonNode: %s. Reason: %s ", descriptor, e.getMessage()), e);
- }
- }
+ widgetType.setDescriptor(descriptor);
return widgetType;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
index 0d04577221..8d0100d9ad 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
@@ -41,8 +41,6 @@ public abstract class JpaAbstractDao, D> implements Dao<
protected abstract Class getEntityClass();
- protected abstract String getColumnFamilyName();
-
protected abstract CrudRepository getCrudRepository();
protected boolean isSearchTextDao() {
@@ -93,7 +91,6 @@ public abstract class JpaAbstractDao, D> implements Dao<
@Override
public List find() {
- log.debug("Get all entities from column family {}", getColumnFamilyName());
List entities = Lists.newArrayList(getCrudRepository().findAll());
return DaoUtil.convertDataList(entities);
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/JpaBaseComponentDescriptorDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/JpaBaseComponentDescriptorDao.java
index 440cce02f6..596d142dd9 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/JpaBaseComponentDescriptorDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/component/JpaBaseComponentDescriptorDao.java
@@ -50,11 +50,6 @@ public class JpaBaseComponentDescriptorDao extends JpaAbstractSearchTextDao getCrudRepository() {
return componentDescriptorRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java
index 5687ebbc99..b26be064f6 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/customer/CustomerRepository.java
@@ -40,6 +40,4 @@ public interface CustomerRepository extends CrudRepository
"AND ID > ?4 ORDER BY ID LIMIT ?1")
List findByTenantIdNextPage(int limit, UUID tenantId, String textSearch, UUID idOffset);
- @Query(nativeQuery = true, value = "SELECT * FROM CUSTOMER WHERE TENANT_ID = ?1")
- List findByTenantId(UUID tenantId);
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java
index 07d7fc9c1b..3dfaccdec8 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/customer/JpaCustomerDao.java
@@ -45,11 +45,6 @@ public class JpaCustomerDao extends JpaAbstractSearchTextDao getCrudRepository() {
return customerRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardDao.java
index 5d0c7bb86f..5f14110af4 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardDao.java
@@ -43,11 +43,6 @@ public class JpaDashboardDao extends JpaAbstractSearchTextDao getCrudRepository() {
return dashboardRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java
index 698cb31684..81f73092d5 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java
@@ -46,11 +46,6 @@ public class JpaDashboardInfoDao extends JpaAbstractSearchTextDao getCrudRepository() {
return deviceCredentialsRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java
index 730eb8bd13..c9b9c75d89 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java
@@ -51,11 +51,6 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao
return DeviceEntity.class;
}
- @Override
- protected String getColumnFamilyName() {
- return DEVICE_COLUMN_FAMILY_NAME;
- }
-
@Override
protected CrudRepository getCrudRepository() {
return deviceRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java
index 9dd6070e1c..efe5908f43 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java
@@ -66,11 +66,6 @@ public class JpaBaseEventDao extends JpaAbstractSearchTimeDao getCrudRepository() {
return eventRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java
index 44e43d5e03..b4ad114a41 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java
@@ -51,11 +51,6 @@ public class JpaBasePluginDao extends JpaAbstractSearchTextDao getCrudRepository() {
return pluginMetaDataRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java
index b368b3bf9c..b5e6bf556d 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java
@@ -50,10 +50,6 @@ public class JpaBaseRuleDao extends JpaAbstractSearchTextDao getEntityClass() {
return RuleMetaDataEntity.class;
}
- @Override
- protected String getColumnFamilyName() {
- return ModelConstants.RULE_COLUMN_FAMILY_NAME;
- }
@Override
protected CrudRepository getCrudRepository() {
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/settings/JpaAdminSettingsDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/settings/JpaAdminSettingsDao.java
index 7373cd8140..b1e2326f41 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/settings/JpaAdminSettingsDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/settings/JpaAdminSettingsDao.java
@@ -40,11 +40,6 @@ public class JpaAdminSettingsDao extends JpaAbstractDao getCrudRepository() {
return adminSettingsRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java
index cbe173831d..f2feef25f5 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/tenant/JpaTenantDao.java
@@ -47,11 +47,6 @@ public class JpaTenantDao extends JpaAbstractSearchTextDao
return TenantEntity.class;
}
- @Override
- protected String getColumnFamilyName() {
- return TENANT_COLUMN_FAMILY_NAME;
- }
-
@Override
protected CrudRepository getCrudRepository() {
return tenantRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java
index fa119b679f..828909cca2 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java
@@ -44,11 +44,6 @@ public class JpaUserCredentialsDao extends JpaAbstractDao getCrudRepository() {
return userCredentialsRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java
index 3008f59016..1a3c6eaf2d 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java
@@ -45,11 +45,6 @@ public class JpaUserDao extends JpaAbstractDao implements User
return UserEntity.class;
}
- @Override
- protected String getColumnFamilyName() {
- return ModelConstants.USER_COLUMN_FAMILY_NAME;
- }
-
@Override
protected CrudRepository getCrudRepository() {
return userRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDao.java
index 2146a8ff11..58f9346239 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetTypeDao.java
@@ -45,11 +45,6 @@ public class JpaWidgetTypeDao extends JpaAbstractDao getCrudRepository() {
return widgetTypeRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java
index 4288e5ab74..b2f0de6b1f 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java
@@ -47,11 +47,6 @@ public class JpaWidgetsBundleDao extends JpaAbstractSearchTextDao getCrudRepository() {
return widgetsBundleRepository;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/JacksonUtil.java b/dao/src/main/java/org/thingsboard/server/dao/util/JacksonUtil.java
new file mode 100644
index 0000000000..5b1f5455ce
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/util/JacksonUtil.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright © 2016-2017 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.util;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+
+/**
+ * Created by Valerii Sosliuk on 5/12/2017.
+ */
+public class JacksonUtil {
+
+ public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+ public static T fromString(String string, Class clazz) {
+ try {
+ return OBJECT_MAPPER.readValue(string, clazz);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("The given string value: "
+ + string + " cannot be transformed to Json object");
+ }
+ }
+
+ public static String toString(Object value) {
+ try {
+ return OBJECT_MAPPER.writeValueAsString(value);
+ } catch (JsonProcessingException e) {
+ throw new IllegalArgumentException("The given Json object value: "
+ + value + " cannot be transformed to a String");
+ }
+ }
+
+ public static JsonNode toJsonNode(String value) {
+ try {
+ return OBJECT_MAPPER.readTree(value);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public static T clone(T value) {
+ return fromString(toString(value), (Class) value.getClass());
+ }
+}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/JsonBinarySqlTypeDescriptor.java b/dao/src/main/java/org/thingsboard/server/dao/util/JsonBinarySqlTypeDescriptor.java
new file mode 100644
index 0000000000..77c768712e
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/util/JsonBinarySqlTypeDescriptor.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright © 2016-2017 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.util;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.hibernate.type.descriptor.ValueBinder;
+import org.hibernate.type.descriptor.ValueExtractor;
+import org.hibernate.type.descriptor.WrapperOptions;
+import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
+import org.hibernate.type.descriptor.sql.BasicBinder;
+import org.hibernate.type.descriptor.sql.BasicExtractor;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+
+import java.sql.*;
+
+/**
+ * Created by Valerii Sosliuk on 5/12/2017.
+ */
+public class JsonBinarySqlTypeDescriptor
+ implements SqlTypeDescriptor {
+
+ public static final JsonBinarySqlTypeDescriptor INSTANCE =
+ new JsonBinarySqlTypeDescriptor();
+
+ @Override
+ public int getSqlType() {
+ return Types.OTHER;
+ }
+
+ @Override
+ public boolean canBeRemapped() {
+ return true;
+ }
+
+ @Override
+ public ValueExtractor getExtractor(
+ final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicExtractor(javaTypeDescriptor, this) {
+ @Override
+ protected X doExtract(
+ ResultSet rs,
+ String name,
+ WrapperOptions options) throws SQLException {
+ return javaTypeDescriptor.wrap(
+ rs.getObject(name), options
+ );
+ }
+
+ @Override
+ protected X doExtract(
+ CallableStatement statement,
+ int index,
+ WrapperOptions options) throws SQLException {
+ return javaTypeDescriptor.wrap(
+ statement.getObject(index), options
+ );
+ }
+
+ @Override
+ protected X doExtract(
+ CallableStatement statement,
+ String name,
+ WrapperOptions options) throws SQLException {
+ return javaTypeDescriptor.wrap(
+ statement.getObject(name), options
+ );
+ }
+ };
+ }
+
+ @Override
+ public ValueBinder getBinder(
+ final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder(javaTypeDescriptor, this) {
+ @Override
+ protected void doBind(
+ PreparedStatement st,
+ X value,
+ int index,
+ WrapperOptions options) throws SQLException {
+ st.setObject(index,
+ javaTypeDescriptor.unwrap(
+ value, JsonNode.class, options), getSqlType()
+ );
+ }
+
+ @Override
+ protected void doBind(
+ CallableStatement st,
+ X value,
+ String name,
+ WrapperOptions options)
+ throws SQLException {
+ st.setObject(name,
+ javaTypeDescriptor.unwrap(
+ value, JsonNode.class, options), getSqlType()
+ );
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/JsonBinaryType.java b/dao/src/main/java/org/thingsboard/server/dao/util/JsonBinaryType.java
new file mode 100644
index 0000000000..96a49c9a39
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/util/JsonBinaryType.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright © 2016-2017 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.util;
+
+import org.hibernate.type.AbstractSingleColumnStandardBasicType;
+import org.hibernate.usertype.DynamicParameterizedType;
+
+import java.util.Properties;
+
+/**
+ * Created by Valerii Sosliuk on 5/12/2017.
+ */
+public class JsonBinaryType extends AbstractSingleColumnStandardBasicType