thingsboard-memoizeit

Changes

dao/pom.xml 4(+4 -0)

pom.xml 5(+5 -0)

Details

diff --git a/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java b/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java
index 876b525..ed75b10 100644
--- a/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java
@@ -15,16 +15,7 @@
  */
 package org.thingsboard.server.actors.plugin;
 
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.stream.Collectors;
-
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.ResultSetFuture;
-import com.datastax.driver.core.Row;
+import akka.actor.ActorRef;
 import com.google.common.base.Function;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
@@ -32,18 +23,20 @@ import com.google.common.util.concurrent.ListenableFuture;
 import lombok.extern.slf4j.Slf4j;
 import org.thingsboard.server.common.data.DataConstants;
 import org.thingsboard.server.common.data.Device;
-import org.thingsboard.server.common.data.id.*;
+import org.thingsboard.server.common.data.id.CustomerId;
+import org.thingsboard.server.common.data.id.DeviceId;
+import org.thingsboard.server.common.data.id.PluginId;
+import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.kv.AttributeKey;
 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
 import org.thingsboard.server.common.data.kv.TsKvEntry;
 import org.thingsboard.server.common.data.kv.TsKvQuery;
-import org.thingsboard.server.common.data.page.TextPageData;
 import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.common.msg.cluster.ServerAddress;
 import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
 import org.thingsboard.server.extensions.api.plugins.PluginApiCallSecurityContext;
-import org.thingsboard.server.extensions.api.plugins.PluginContext;
 import org.thingsboard.server.extensions.api.plugins.PluginCallback;
+import org.thingsboard.server.extensions.api.plugins.PluginContext;
 import org.thingsboard.server.extensions.api.plugins.msg.PluginToRuleMsg;
 import org.thingsboard.server.extensions.api.plugins.msg.TimeoutMsg;
 import org.thingsboard.server.extensions.api.plugins.msg.ToDeviceRpcRequest;
@@ -52,10 +45,12 @@ import org.thingsboard.server.extensions.api.plugins.rpc.RpcMsg;
 import org.thingsboard.server.extensions.api.plugins.ws.PluginWebsocketSessionRef;
 import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
 
-import akka.actor.ActorRef;
-import org.w3c.dom.Attr;
-
 import javax.annotation.Nullable;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
 
 @Slf4j
 public final class PluginProcessingContext implements PluginContext {
diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java
index 1b6696f..034206f 100644
--- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java
@@ -15,8 +15,6 @@
  */
 package org.thingsboard.server.controller;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
index b08a964..3df1bae 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
@@ -23,19 +23,16 @@ 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.common.data.id.UUIDBased;
 import org.thingsboard.server.common.data.page.TextPageData;
 import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.common.data.security.DeviceCredentials;
 import org.thingsboard.server.dao.exception.IncorrectParameterException;
 import org.thingsboard.server.dao.model.ModelConstants;
 import org.thingsboard.server.exception.ThingsboardException;
-import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
 import org.thingsboard.server.service.security.model.SecurityUser;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.UUID;
 
 @RestController
 @RequestMapping("/api")
diff --git a/application/src/main/java/org/thingsboard/server/controller/PluginController.java b/application/src/main/java/org/thingsboard/server/controller/PluginController.java
index 5132664..5dd14cc 100644
--- a/application/src/main/java/org/thingsboard/server/controller/PluginController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/PluginController.java
@@ -25,7 +25,6 @@ import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
 import org.thingsboard.server.common.data.plugin.PluginMetaData;
 import org.thingsboard.server.common.data.security.Authority;
-import org.thingsboard.server.common.data.widget.WidgetsBundle;
 import org.thingsboard.server.dao.model.ModelConstants;
 import org.thingsboard.server.exception.ThingsboardException;
 
diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml
index 778406a..8766e57 100644
--- a/application/src/main/resources/thingsboard.yml
+++ b/application/src/main/resources/thingsboard.yml
@@ -188,3 +188,15 @@ cache:
 updates:
   # Enable/disable updates checking.
   enabled: "${UPDATES_ENABLED:true}"
+
+cassandra:
+  enabled: "${CASSANDRA_ENABLED:true}"
+
+# SQL DAO Configuration
+
+sql:
+  enabled: "${SQL_ENABLED:false}"
+  datasource:
+    url: "${SQL_DATASOURCE_URL:jdbc:postgresql://localhost:5432/thingsboard}"
+    username: "${SQL_DATASOURCE_USERNAME:postgres}"
+    password: "${SQL_DATASOURCE_PASSWORD:postgres}"
diff --git a/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java
index e6eb243..329b42d 100644
--- a/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java
+++ b/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java
@@ -35,7 +35,6 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
-import com.datastax.driver.core.utils.UUIDs;
 import com.fasterxml.jackson.core.type.TypeReference;
 
 public class DashboardControllerTest extends AbstractControllerTest {
diff --git a/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java
index 69bb761..0f2fa12 100644
--- a/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java
+++ b/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java
@@ -42,7 +42,6 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
-import com.datastax.driver.core.utils.UUIDs;
 import com.fasterxml.jackson.core.type.TypeReference;
 
 public class DeviceControllerTest extends AbstractControllerTest {

dao/pom.xml 4(+4 -0)

diff --git a/dao/pom.xml b/dao/pom.xml
index 146b8c1..977be95 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -150,6 +150,10 @@
             <groupId>org.bouncycastle</groupId>
             <artifactId>bcprov-jdk15on</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesDao.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesDao.java
index 3fb8ee2..6696f39 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesDao.java
@@ -15,9 +15,6 @@
  */
 package org.thingsboard.server.dao.attributes;
 
-// CASSANDRA ???
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.ResultSetFuture;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.thingsboard.server.common.data.id.EntityId;
 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java
index ccca460..222ffa3 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java
@@ -15,8 +15,6 @@
  */
 package org.thingsboard.server.dao.attributes;
 
-// CASSANDRA ???
-import com.datastax.driver.core.ResultSet;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.thingsboard.server.common.data.id.EntityId;
 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java
index 6fd734a..5ed231b 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java
@@ -15,9 +15,6 @@
  */
 package org.thingsboard.server.dao.attributes;
 
-// CASSANDRA ???
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.ResultSetFuture;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java
index ee9d5e0..99c82a0 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java
@@ -27,7 +27,6 @@ import com.google.common.base.Function;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import lombok.extern.slf4j.Slf4j;
-import org.thingsboard.server.common.data.SearchTextBased;
 import org.thingsboard.server.dao.model.BaseEntity;
 import org.thingsboard.server.dao.model.ModelConstants;
 import org.thingsboard.server.dao.model.SearchTextEntity;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/component/CassandraBaseComponentDescriptorDao.java b/dao/src/main/java/org/thingsboard/server/dao/component/CassandraBaseComponentDescriptorDao.java
index 62eb957..0426a33 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/component/CassandraBaseComponentDescriptorDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/component/CassandraBaseComponentDescriptorDao.java
@@ -29,7 +29,7 @@ import org.thingsboard.server.common.data.plugin.ComponentScope;
 import org.thingsboard.server.common.data.plugin.ComponentType;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.ComponentDescriptorEntity;
+import org.thingsboard.server.dao.model.nosql.ComponentDescriptorEntity;
 import org.thingsboard.server.dao.model.ModelConstants;
 
 import java.util.Arrays;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/customer/CassandraCustomerDao.java b/dao/src/main/java/org/thingsboard/server/dao/customer/CassandraCustomerDao.java
index 18f35e6..1bb682b 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/customer/CassandraCustomerDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/customer/CassandraCustomerDao.java
@@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.Customer;
 import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.CustomerEntity;
+import org.thingsboard.server.dao.model.nosql.CustomerEntity;
 import org.thingsboard.server.dao.model.ModelConstants;
 
 import java.util.Arrays;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/CassandraDashboardDao.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/CassandraDashboardDao.java
index 97a5c7a..82d5a26 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/CassandraDashboardDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/CassandraDashboardDao.java
@@ -18,7 +18,7 @@ package org.thingsboard.server.dao.dashboard;
 import org.springframework.stereotype.Component;
 import org.thingsboard.server.common.data.Dashboard;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
-import org.thingsboard.server.dao.model.DashboardEntity;
+import org.thingsboard.server.dao.model.nosql.DashboardEntity;
 
 import static org.thingsboard.server.dao.model.ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME;
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/CassandraDashboardInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/CassandraDashboardInfoDao.java
index 19527c7..b0c3e89 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/CassandraDashboardInfoDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/CassandraDashboardInfoDao.java
@@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.DashboardInfo;
 import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.DashboardInfoEntity;
+import org.thingsboard.server.dao.model.nosql.DashboardInfoEntity;
 
 import java.util.Arrays;
 import java.util.Collections;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceCredentialsDao.java b/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceCredentialsDao.java
index c96367e..14ac5bf 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceCredentialsDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceCredentialsDao.java
@@ -21,7 +21,7 @@ import org.springframework.stereotype.Component;
 import org.thingsboard.server.common.data.security.DeviceCredentials;
 import org.thingsboard.server.dao.CassandraAbstractModelDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.DeviceCredentialsEntity;
+import org.thingsboard.server.dao.model.nosql.DeviceCredentialsEntity;
 import org.thingsboard.server.dao.model.ModelConstants;
 
 import java.util.UUID;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java b/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java
index 814976e..b326fcb 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java
@@ -23,7 +23,7 @@ import org.thingsboard.server.common.data.Device;
 import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.DeviceEntity;
+import org.thingsboard.server.dao.model.nosql.DeviceEntity;
 
 import java.util.*;
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
index 2588650..a5707ce 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
@@ -15,8 +15,6 @@
  */
 package org.thingsboard.server.dao.device;
 
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.RandomStringUtils;
@@ -35,7 +33,6 @@ import org.thingsboard.server.common.data.security.DeviceCredentials;
 import org.thingsboard.server.common.data.security.DeviceCredentialsType;
 import org.thingsboard.server.dao.customer.CustomerDao;
 import org.thingsboard.server.dao.exception.DataValidationException;
-import org.thingsboard.server.dao.model.DeviceEntity;
 import org.thingsboard.server.dao.service.DataValidator;
 import org.thingsboard.server.dao.service.PaginatedRemover;
 import org.thingsboard.server.dao.tenant.TenantDao;
@@ -43,8 +40,6 @@ import org.thingsboard.server.dao.tenant.TenantDao;
 import java.util.List;
 import java.util.Optional;
 
-import static org.thingsboard.server.dao.DaoUtil.convertDataList;
-import static org.thingsboard.server.dao.DaoUtil.getData;
 import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
 import static org.thingsboard.server.dao.service.Validator.validateId;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java
index 65fc567..c5c4e47 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/event/BaseEventService.java
@@ -15,15 +15,12 @@
  */
 package org.thingsboard.server.dao.event;
 
-// CASSANDRA ???
-import com.datastax.driver.core.utils.UUIDs;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.thingsboard.server.common.data.Event;
 import org.thingsboard.server.common.data.id.EntityId;
-import org.thingsboard.server.common.data.id.EventId;
 import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.page.TimePageData;
 import org.thingsboard.server.common.data.page.TimePageLink;
@@ -33,30 +30,16 @@ import org.thingsboard.server.dao.service.DataValidator;
 import java.util.List;
 import java.util.Optional;
 
-import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
-
 @Service
 @Slf4j
 public class BaseEventService implements EventService {
 
-    private final TenantId systemTenantId = new TenantId(NULL_UUID);
-
     @Autowired
     public EventDao eventDao;
 
     @Override
     public Event save(Event event) {
         eventValidator.validate(event);
-        if (event.getTenantId() == null) {
-            log.trace("Save system event with predefined id {}", systemTenantId);
-            event.setTenantId(systemTenantId);
-        }
-        if (event.getId() == null) {
-            event.setId(new EventId(UUIDs.timeBased()));
-        }
-        if (StringUtils.isEmpty(event.getUid())) {
-            event.setUid(event.getId().toString());
-        }
         return eventDao.save(event);
     }
 
@@ -66,13 +49,6 @@ public class BaseEventService implements EventService {
         if (StringUtils.isEmpty(event.getUid())) {
             throw new DataValidationException("Event uid should be specified!.");
         }
-        if (event.getTenantId() == null) {
-            log.trace("Save system event with predefined id {}", systemTenantId);
-            event.setTenantId(systemTenantId);
-        }
-        if (event.getId() == null) {
-            event.setId(new EventId(UUIDs.timeBased()));
-        }
         Optional<Event> result = eventDao.saveIfNotExists(event);
         return result.isPresent() ? Optional.of(result.get()) : Optional.empty();
     }
@@ -98,13 +74,13 @@ public class BaseEventService implements EventService {
     @Override
     public TimePageData<Event> findEvents(TenantId tenantId, EntityId entityId, TimePageLink pageLink) {
         List<Event> events = eventDao.findEvents(tenantId.getId(), entityId, pageLink);
-        return new TimePageData<Event>(events, pageLink);
+        return new TimePageData<>(events, pageLink);
     }
 
     @Override
     public TimePageData<Event> findEvents(TenantId tenantId, EntityId entityId, String eventType, TimePageLink pageLink) {
         List<Event> events = eventDao.findEvents(tenantId.getId(), entityId, eventType, pageLink);
-        return new TimePageData<Event>(events, pageLink);
+        return new TimePageData<>(events, pageLink);
     }
 
     private DataValidator<Event> eventValidator =
diff --git a/dao/src/main/java/org/thingsboard/server/dao/event/CassandraBaseEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/event/CassandraBaseEventDao.java
index 1bdf452..3598d2a 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/event/CassandraBaseEventDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/event/CassandraBaseEventDao.java
@@ -21,13 +21,16 @@ import com.datastax.driver.core.querybuilder.QueryBuilder;
 import com.datastax.driver.core.querybuilder.Select;
 import com.datastax.driver.core.utils.UUIDs;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
 import org.thingsboard.server.common.data.Event;
 import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.EventId;
+import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.page.TimePageLink;
 import org.thingsboard.server.dao.CassandraAbstractSearchTimeDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.EventEntity;
+import org.thingsboard.server.dao.model.nosql.EventEntity;
 import org.thingsboard.server.dao.model.ModelConstants;
 
 import java.util.Arrays;
@@ -43,6 +46,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.*;
 @Slf4j
 public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventEntity, Event> implements EventDao {
 
+    private final TenantId systemTenantId = new TenantId(NULL_UUID);
+
     @Override
     protected Class<EventEntity> getColumnFamilyClass() {
         return EventEntity.class;
@@ -56,11 +61,28 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
     @Override
     public Event save(Event event) {
         log.debug("Save event [{}] ", event);
+        if (event.getTenantId() == null) {
+            log.trace("Save system event with predefined id {}", systemTenantId);
+            event.setTenantId(systemTenantId);
+        }
+        if (event.getId() == null) {
+            event.setId(new EventId(UUIDs.timeBased()));
+        }
+        if (StringUtils.isEmpty(event.getUid())) {
+            event.setUid(event.getId().toString());
+        }
         return save(new EventEntity(event), false).orElse(null);
     }
 
     @Override
     public Optional<Event> saveIfNotExists(Event event) {
+        if (event.getTenantId() == null) {
+            log.trace("Save system event with predefined id {}", systemTenantId);
+            event.setTenantId(systemTenantId);
+        }
+        if (event.getId() == null) {
+            event.setId(new EventId(UUIDs.timeBased()));
+        }
         return save(new EventEntity(event), true);
     }
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java
new file mode 100644
index 0000000..167518a
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java
@@ -0,0 +1,42 @@
+/**
+ * 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;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Configuration;
+
+import javax.sql.DataSource;
+
+/**
+ * @author Valerii Sosliuk
+ */
+@Configuration
+@ConditionalOnProperty(prefix="sql", value="enabled",havingValue = "true", matchIfMissing = false)
+public class JpaDaoConfig {
+
+    @Value("sql.datasource.url")
+    private String url;
+    @Value("sql.datasource.username")
+    private String username;
+    @Value("sql.datasource.password")
+    private String password;
+
+    public DataSource dataSource() {
+        return DataSourceBuilder.create().url(url).username(username).password(password).build();
+    }
+}
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
new file mode 100644
index 0000000..40580ee
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java
@@ -0,0 +1,145 @@
+/**
+ * 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.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.fasterxml.jackson.databind.JsonNode;
+import org.thingsboard.server.common.data.AdminSettings;
+import org.thingsboard.server.common.data.id.AdminSettingsId;
+import org.thingsboard.server.dao.model.BaseEntity;
+
+import java.util.UUID;
+
+import static org.thingsboard.server.dao.model.ModelConstants.*;
+
+@Entity
+@Table(name = ADMIN_SETTINGS_COLUMN_FAMILY_NAME)
+public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
+
+    @Transient
+    private static final long serialVersionUID = 842759712850362147L;
+
+    @Id
+    @Column(name = ID_PROPERTY)
+    private UUID id;
+    
+    @Column(name = ADMIN_SETTINGS_KEY_PROPERTY)
+    private String key;
+
+    @Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY)
+    private JsonNode jsonValue;
+
+    public AdminSettingsEntity() {
+        super();
+    }
+
+    public AdminSettingsEntity(AdminSettings adminSettings) {
+        if (adminSettings.getId() != null) {
+            this.id = adminSettings.getId().getId();
+        }
+        this.key = adminSettings.getKey();
+        this.jsonValue = adminSettings.getJsonValue();
+    }
+    
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+    
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public JsonNode getJsonValue() {
+        return jsonValue;
+    }
+
+    public void setJsonValue(JsonNode jsonValue) {
+        this.jsonValue = jsonValue;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((jsonValue == null) ? 0 : jsonValue.hashCode());
+        result = prime * result + ((key == null) ? 0 : key.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        AdminSettingsEntity other = (AdminSettingsEntity) obj;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        if (jsonValue == null) {
+            if (other.jsonValue != null)
+                return false;
+        } else if (!jsonValue.equals(other.jsonValue))
+            return false;
+        if (key == null) {
+            if (other.key != null)
+                return false;
+        } else if (!key.equals(other.key))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("AdminSettingsEntity [id=");
+        builder.append(id);
+        builder.append(", key=");
+        builder.append(key);
+        builder.append(", jsonValue=");
+        builder.append(jsonValue);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public AdminSettings toData() {
+        AdminSettings adminSettings = new AdminSettings(new AdminSettingsId(id));
+        adminSettings.setCreatedTime(UUIDs.unixTimestamp(id));
+        adminSettings.setKey(key);
+        adminSettings.setJsonValue(jsonValue);
+        return adminSettings;
+    }
+
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..53bac76
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java
@@ -0,0 +1,164 @@
+/**
+ * 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.model.sql;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import com.fasterxml.jackson.databind.JsonNode;
+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 java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME)
+public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDescriptor> {
+
+    @Transient
+    private static final long serialVersionUID = 253590350877992402L;
+
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+
+    @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_TYPE_PROPERTY)
+    private ComponentType type;
+
+    @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_SCOPE_PROPERTY)
+    private ComponentScope scope;
+
+    @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_NAME_PROPERTY)
+    private String name;
+
+    @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY)
+    private String clazz;
+
+    @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY)
+    private JsonNode configurationDescriptor;
+
+    @Column(name = ModelConstants.COMPONENT_DESCRIPTOR_ACTIONS_PROPERTY)
+    private String actions;
+
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+
+    public ComponentDescriptorEntity() {
+    }
+
+    public ComponentDescriptorEntity(ComponentDescriptor component) {
+        if (component.getId() != null) {
+            this.id = component.getId().getId();
+        }
+        this.actions = component.getActions();
+        this.type = component.getType();
+        this.scope = component.getScope();
+        this.name = component.getName();
+        this.clazz = component.getClazz();
+        this.configurationDescriptor = component.getConfigurationDescriptor();
+        this.searchText = component.getName();
+    }
+
+    @Override
+    public ComponentDescriptor toData() {
+        ComponentDescriptor data = new ComponentDescriptor(new ComponentDescriptorId(id));
+        data.setType(type);
+        data.setScope(scope);
+        data.setName(this.getName());
+        data.setClazz(this.getClazz());
+        data.setActions(this.getActions());
+        data.setConfigurationDescriptor(this.getConfigurationDescriptor());
+        return data;
+    }
+
+    @Override
+    public UUID getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public String getActions() {
+        return actions;
+    }
+
+    public void setActions(String actions) {
+        this.actions = actions;
+    }
+
+    public ComponentType getType() {
+        return type;
+    }
+
+    public void setType(ComponentType type) {
+        this.type = type;
+    }
+
+    public ComponentScope getScope() {
+        return scope;
+    }
+
+    public void setScope(ComponentScope scope) {
+        this.scope = scope;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getClazz() {
+        return clazz;
+    }
+
+    public void setClazz(String clazz) {
+        this.clazz = clazz;
+    }
+
+    public JsonNode getConfigurationDescriptor() {
+        return configurationDescriptor;
+    }
+
+    public void setConfigurationDescriptor(JsonNode configurationDescriptor) {
+        this.configurationDescriptor = configurationDescriptor;
+    }
+
+    public String getSearchText() {
+        return searchText;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+
+    @Override
+    public String getSearchTextSource() {
+        return searchText;
+    }
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java
new file mode 100644
index 0000000..bf7404f
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/CustomerEntity.java
@@ -0,0 +1,351 @@
+/**
+ * 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.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.fasterxml.jackson.databind.JsonNode;
+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.ModelConstants;
+import org.thingsboard.server.dao.model.SearchTextEntity;
+
+import java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.CUSTOMER_COLUMN_FAMILY_NAME)
+public final class CustomerEntity implements SearchTextEntity<Customer> {
+
+    @Transient
+    private static final long serialVersionUID = 8951342124082981556L;
+
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+    
+    @Column(name = ModelConstants.CUSTOMER_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+    
+    @Column(name = ModelConstants.CUSTOMER_TITLE_PROPERTY)
+    private String title;
+    
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+    
+    @Column(name = ModelConstants.COUNTRY_PROPERTY)
+    private String country;
+    
+    @Column(name = ModelConstants.STATE_PROPERTY)
+    private String state;
+
+    @Column(name = ModelConstants.CITY_PROPERTY)
+    private String city;
+
+    @Column(name = ModelConstants.ADDRESS_PROPERTY)
+    private String address;
+
+    @Column(name = ModelConstants.ADDRESS2_PROPERTY)
+    private String address2;
+
+    @Column(name = ModelConstants.ZIP_PROPERTY)
+    private String zip;
+
+    @Column(name = ModelConstants.PHONE_PROPERTY)
+    private String phone;
+
+    @Column(name = ModelConstants.EMAIL_PROPERTY)
+    private String email;
+
+    @Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY)
+    private JsonNode additionalInfo;
+
+    public CustomerEntity() {
+        super();
+    }
+
+    public CustomerEntity(Customer customer) {
+        if (customer.getId() != null) {
+            this.id = customer.getId().getId();
+        }
+        this.tenantId = customer.getTenantId().getId();
+        this.title = customer.getTitle();
+        this.country = customer.getCountry();
+        this.state = customer.getState();
+        this.city = customer.getCity();
+        this.address = customer.getAddress();
+        this.address2 = customer.getAddress2();
+        this.zip = customer.getZip();
+        this.phone = customer.getPhone();
+        this.email = customer.getEmail();
+        this.additionalInfo = customer.getAdditionalInfo();
+    }
+    
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getCountry() {
+        return country;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getAddress2() {
+        return address2;
+    }
+
+    public void setAddress2(String address2) {
+        this.address2 = address2;
+    }
+
+    public String getZip() {
+        return zip;
+    }
+
+    public void setZip(String zip) {
+        this.zip = zip;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public JsonNode getAdditionalInfo() {
+        return additionalInfo;
+    }
+
+    public void setAdditionalInfo(JsonNode additionalInfo) {
+        this.additionalInfo = additionalInfo;
+    }
+    
+    @Override
+    public String getSearchTextSource() {
+        return title;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+    
+    public String getSearchText() {
+        return searchText;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode());
+        result = prime * result + ((address == null) ? 0 : address.hashCode());
+        result = prime * result + ((address2 == null) ? 0 : address2.hashCode());
+        result = prime * result + ((city == null) ? 0 : city.hashCode());
+        result = prime * result + ((country == null) ? 0 : country.hashCode());
+        result = prime * result + ((email == null) ? 0 : email.hashCode());
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((phone == null) ? 0 : phone.hashCode());
+        result = prime * result + ((state == null) ? 0 : state.hashCode());
+        result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
+        result = prime * result + ((title == null) ? 0 : title.hashCode());
+        result = prime * result + ((zip == null) ? 0 : zip.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        CustomerEntity other = (CustomerEntity) obj;
+        if (additionalInfo == null) {
+            if (other.additionalInfo != null)
+                return false;
+        } else if (!additionalInfo.equals(other.additionalInfo))
+            return false;
+        if (address == null) {
+            if (other.address != null)
+                return false;
+        } else if (!address.equals(other.address))
+            return false;
+        if (address2 == null) {
+            if (other.address2 != null)
+                return false;
+        } else if (!address2.equals(other.address2))
+            return false;
+        if (city == null) {
+            if (other.city != null)
+                return false;
+        } else if (!city.equals(other.city))
+            return false;
+        if (country == null) {
+            if (other.country != null)
+                return false;
+        } else if (!country.equals(other.country))
+            return false;
+        if (email == null) {
+            if (other.email != null)
+                return false;
+        } else if (!email.equals(other.email))
+            return false;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        if (phone == null) {
+            if (other.phone != null)
+                return false;
+        } else if (!phone.equals(other.phone))
+            return false;
+        if (state == null) {
+            if (other.state != null)
+                return false;
+        } else if (!state.equals(other.state))
+            return false;
+        if (tenantId == null) {
+            if (other.tenantId != null)
+                return false;
+        } else if (!tenantId.equals(other.tenantId))
+            return false;
+        if (title == null) {
+            if (other.title != null)
+                return false;
+        } else if (!title.equals(other.title))
+            return false;
+        if (zip == null) {
+            if (other.zip != null)
+                return false;
+        } else if (!zip.equals(other.zip))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("CustomerEntity [id=");
+        builder.append(id);
+        builder.append(", tenantId=");
+        builder.append(tenantId);
+        builder.append(", title=");
+        builder.append(title);
+        builder.append(", country=");
+        builder.append(country);
+        builder.append(", state=");
+        builder.append(state);
+        builder.append(", city=");
+        builder.append(city);
+        builder.append(", address=");
+        builder.append(address);
+        builder.append(", address2=");
+        builder.append(address2);
+        builder.append(", zip=");
+        builder.append(zip);
+        builder.append(", phone=");
+        builder.append(phone);
+        builder.append(", email=");
+        builder.append(email);
+        builder.append(", additionalInfo=");
+        builder.append(additionalInfo);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public Customer toData() {
+        Customer customer = new Customer(new CustomerId(id));
+        customer.setCreatedTime(UUIDs.unixTimestamp(id));
+        customer.setTenantId(new TenantId(tenantId));
+        customer.setTitle(title);
+        customer.setCountry(country);
+        customer.setState(state);
+        customer.setCity(city);
+        customer.setAddress(address);
+        customer.setAddress2(address2);
+        customer.setZip(zip);
+        customer.setPhone(phone);
+        customer.setEmail(email);
+        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
new file mode 100644
index 0000000..12a12c1
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java
@@ -0,0 +1,221 @@
+/**
+ * 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.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.fasterxml.jackson.databind.JsonNode;
+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 java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME)
+public final class DashboardEntity implements SearchTextEntity<Dashboard> {
+
+    @Transient
+    private static final long serialVersionUID = -4838084363113078898L;
+
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+    
+    @Column(name = ModelConstants.DASHBOARD_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @Column(name = ModelConstants.DASHBOARD_CUSTOMER_ID_PROPERTY)
+    private UUID customerId;
+
+    @Column(name = ModelConstants.DASHBOARD_TITLE_PROPERTY)
+    private String title;
+    
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+    
+    @Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY)
+    private JsonNode configuration;
+
+    public DashboardEntity() {
+        super();
+    }
+
+    public DashboardEntity(Dashboard dashboard) {
+        if (dashboard.getId() != null) {
+            this.id = dashboard.getId().getId();
+        }
+        if (dashboard.getTenantId() != null) {
+            this.tenantId = dashboard.getTenantId().getId();
+        }
+        if (dashboard.getCustomerId() != null) {
+            this.customerId = dashboard.getCustomerId().getId();
+        }
+        this.title = dashboard.getTitle();
+        this.configuration = dashboard.getConfiguration();
+    }
+    
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public UUID getCustomerId() {
+        return customerId;
+    }
+
+    public void setCustomerId(UUID customerId) {
+        this.customerId = customerId;
+    }
+    
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public JsonNode getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(JsonNode configuration) {
+        this.configuration = configuration;
+    }
+    
+    @Override
+    public String getSearchTextSource() {
+        return title;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+    
+    public String getSearchText() {
+        return searchText;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((configuration == null) ? 0 : configuration.hashCode());
+        result = prime * result + ((customerId == null) ? 0 : customerId.hashCode());
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((searchText == null) ? 0 : searchText.hashCode());
+        result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
+        result = prime * result + ((title == null) ? 0 : title.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        DashboardEntity other = (DashboardEntity) obj;
+        if (configuration == null) {
+            if (other.configuration != null)
+                return false;
+        } else if (!configuration.equals(other.configuration))
+            return false;
+        if (customerId == null) {
+            if (other.customerId != null)
+                return false;
+        } else if (!customerId.equals(other.customerId))
+            return false;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        if (searchText == null) {
+            if (other.searchText != null)
+                return false;
+        } else if (!searchText.equals(other.searchText))
+            return false;
+        if (tenantId == null) {
+            if (other.tenantId != null)
+                return false;
+        } else if (!tenantId.equals(other.tenantId))
+            return false;
+        if (title == null) {
+            if (other.title != null)
+                return false;
+        } else if (!title.equals(other.title))
+            return false;
+        return true;
+    }
+    
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("DashboardEntity [id=");
+        builder.append(id);
+        builder.append(", tenantId=");
+        builder.append(tenantId);
+        builder.append(", customerId=");
+        builder.append(customerId);
+        builder.append(", title=");
+        builder.append(title);
+        builder.append(", searchText=");
+        builder.append(searchText);
+        builder.append(", configuration=");
+        builder.append(configuration);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public Dashboard toData() {
+        Dashboard dashboard = new Dashboard(new DashboardId(id));
+        dashboard.setCreatedTime(UUIDs.unixTimestamp(id));
+        if (tenantId != null) {
+            dashboard.setTenantId(new TenantId(tenantId));
+        }
+        if (customerId != null) {
+            dashboard.setCustomerId(new CustomerId(customerId));
+        }
+        dashboard.setTitle(title);
+        dashboard.setConfiguration(configuration);
+        return dashboard;
+    }
+
+}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java
new file mode 100644
index 0000000..5fb052b
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java
@@ -0,0 +1,199 @@
+/**
+ * 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.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 org.thingsboard.server.common.data.DashboardInfo;
+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 java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME)
+public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> {
+
+    @Transient
+    private static final long serialVersionUID = -5525675905528050250L;
+
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+
+    @Column(name = ModelConstants.DASHBOARD_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @Column(name = ModelConstants.DASHBOARD_CUSTOMER_ID_PROPERTY)
+    private UUID customerId;
+
+    @Column(name = ModelConstants.DASHBOARD_TITLE_PROPERTY)
+    private String title;
+
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+
+    public DashboardInfoEntity() {
+        super();
+    }
+
+    public DashboardInfoEntity(DashboardInfo dashboardInfo) {
+        if (dashboardInfo.getId() != null) {
+            this.id = dashboardInfo.getId().getId();
+        }
+        if (dashboardInfo.getTenantId() != null) {
+            this.tenantId = dashboardInfo.getTenantId().getId();
+        }
+        if (dashboardInfo.getCustomerId() != null) {
+            this.customerId = dashboardInfo.getCustomerId().getId();
+        }
+        this.title = dashboardInfo.getTitle();
+    }
+
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public UUID getCustomerId() {
+        return customerId;
+    }
+
+    public void setCustomerId(UUID customerId) {
+        this.customerId = customerId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    @Override
+    public String getSearchTextSource() {
+        return title;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+
+    public String getSearchText() {
+        return searchText;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((customerId == null) ? 0 : customerId.hashCode());
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((searchText == null) ? 0 : searchText.hashCode());
+        result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
+        result = prime * result + ((title == null) ? 0 : title.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        DashboardInfoEntity other = (DashboardInfoEntity) obj;
+        if (customerId == null) {
+            if (other.customerId != null)
+                return false;
+        } else if (!customerId.equals(other.customerId))
+            return false;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        if (searchText == null) {
+            if (other.searchText != null)
+                return false;
+        } else if (!searchText.equals(other.searchText))
+            return false;
+        if (tenantId == null) {
+            if (other.tenantId != null)
+                return false;
+        } else if (!tenantId.equals(other.tenantId))
+            return false;
+        if (title == null) {
+            if (other.title != null)
+                return false;
+        } else if (!title.equals(other.title))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("DashboardInfoEntity [id=");
+        builder.append(id);
+        builder.append(", tenantId=");
+        builder.append(tenantId);
+        builder.append(", customerId=");
+        builder.append(customerId);
+        builder.append(", title=");
+        builder.append(title);
+        builder.append(", searchText=");
+        builder.append(searchText);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public DashboardInfo toData() {
+        DashboardInfo dashboardInfo = new DashboardInfo(new DashboardId(id));
+        dashboardInfo.setCreatedTime(UUIDs.unixTimestamp(id));
+        if (tenantId != null) {
+            dashboardInfo.setTenantId(new TenantId(tenantId));
+        }
+        if (customerId != null) {
+            dashboardInfo.setCustomerId(new CustomerId(customerId));
+        }
+        dashboardInfo.setTitle(title);
+        return dashboardInfo;
+    }
+
+}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java
new file mode 100644
index 0000000..de43994
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java
@@ -0,0 +1,187 @@
+/**
+ * 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.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 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.BaseEntity;
+import org.thingsboard.server.dao.model.ModelConstants;
+
+import java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.DEVICE_CREDENTIALS_COLUMN_FAMILY_NAME)
+public final class DeviceCredentialsEntity implements BaseEntity<DeviceCredentials> {
+
+    @Transient
+    private static final long serialVersionUID = -2512362753385470464L;
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+    
+    @Column(name = ModelConstants.DEVICE_CREDENTIALS_DEVICE_ID_PROPERTY)
+    private UUID deviceId;
+    
+    @Column(name = ModelConstants.DEVICE_CREDENTIALS_CREDENTIALS_TYPE_PROPERTY)
+    private DeviceCredentialsType credentialsType;
+
+    @Column(name = ModelConstants.DEVICE_CREDENTIALS_CREDENTIALS_ID_PROPERTY)
+    private String credentialsId;
+
+    @Column(name = ModelConstants.DEVICE_CREDENTIALS_CREDENTIALS_VALUE_PROPERTY)
+    private String credentialsValue;
+
+    public DeviceCredentialsEntity() {
+        super();
+    }
+
+    public DeviceCredentialsEntity(DeviceCredentials deviceCredentials) {
+        if (deviceCredentials.getId() != null) {
+            this.id = deviceCredentials.getId().getId();
+        }
+        if (deviceCredentials.getDeviceId() != null) {
+            this.deviceId = deviceCredentials.getDeviceId().getId();
+        }
+        this.credentialsType = deviceCredentials.getCredentialsType();
+        this.credentialsId = deviceCredentials.getCredentialsId();
+        this.credentialsValue = deviceCredentials.getCredentialsValue(); 
+    }
+    
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getDeviceId() {
+        return deviceId;
+    }
+
+    public void setDeviceId(UUID deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public DeviceCredentialsType getCredentialsType() {
+        return credentialsType;
+    }
+
+    public void setCredentialsType(DeviceCredentialsType credentialsType) {
+        this.credentialsType = credentialsType;
+    }
+
+    public String getCredentialsId() {
+        return credentialsId;
+    }
+
+    public void setCredentialsId(String credentialsId) {
+        this.credentialsId = credentialsId;
+    }
+
+    public String getCredentialsValue() {
+        return credentialsValue;
+    }
+
+    public void setCredentialsValue(String credentialsValue) {
+        this.credentialsValue = credentialsValue;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((credentialsId == null) ? 0 : credentialsId.hashCode());
+        result = prime * result + ((credentialsType == null) ? 0 : credentialsType.hashCode());
+        result = prime * result + ((credentialsValue == null) ? 0 : credentialsValue.hashCode());
+        result = prime * result + ((deviceId == null) ? 0 : deviceId.hashCode());
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        DeviceCredentialsEntity other = (DeviceCredentialsEntity) obj;
+        if (credentialsId == null) {
+            if (other.credentialsId != null)
+                return false;
+        } else if (!credentialsId.equals(other.credentialsId))
+            return false;
+        if (credentialsType != other.credentialsType)
+            return false;
+        if (credentialsValue == null) {
+            if (other.credentialsValue != null)
+                return false;
+        } else if (!credentialsValue.equals(other.credentialsValue))
+            return false;
+        if (deviceId == null) {
+            if (other.deviceId != null)
+                return false;
+        } else if (!deviceId.equals(other.deviceId))
+            return false;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("DeviceCredentialsEntity [id=");
+        builder.append(id);
+        builder.append(", deviceId=");
+        builder.append(deviceId);
+        builder.append(", credentialsType=");
+        builder.append(credentialsType);
+        builder.append(", credentialsId=");
+        builder.append(credentialsId);
+        builder.append(", credentialsValue=");
+        builder.append(credentialsValue);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public DeviceCredentials toData() {
+        DeviceCredentials deviceCredentials = new DeviceCredentials(new DeviceCredentialsId(id));
+        deviceCredentials.setCreatedTime(UUIDs.unixTimestamp(id));
+        if (deviceId != null) {
+            deviceCredentials.setDeviceId(new DeviceId(deviceId));
+        }
+        deviceCredentials.setCredentialsType(credentialsType);
+        deviceCredentials.setCredentialsId(credentialsId);
+        deviceCredentials.setCredentialsValue(credentialsValue);
+        return deviceCredentials;
+    }
+
+}
\ 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
new file mode 100644
index 0000000..72c2dd5
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
@@ -0,0 +1,213 @@
+/**
+ * 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.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.fasterxml.jackson.databind.JsonNode;
+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 java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.DEVICE_COLUMN_FAMILY_NAME)
+public final class DeviceEntity implements SearchTextEntity<Device> {
+
+    @Transient
+    private static final long serialVersionUID = 8050086401213322856L;
+
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+    
+    @Column(name = ModelConstants.DEVICE_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @Column(name = ModelConstants.DEVICE_CUSTOMER_ID_PROPERTY)
+    private UUID customerId;
+
+    @Column(name = ModelConstants.DEVICE_NAME_PROPERTY)
+    private String name;
+    
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+    
+    @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY)
+    private JsonNode additionalInfo;
+
+    public DeviceEntity() {
+        super();
+    }
+
+    public DeviceEntity(Device device) {
+        if (device.getId() != null) {
+            this.id = device.getId().getId();
+        }
+        if (device.getTenantId() != null) {
+            this.tenantId = device.getTenantId().getId();
+        }
+        if (device.getCustomerId() != null) {
+            this.customerId = device.getCustomerId().getId();
+        }
+        this.name = device.getName();
+        this.additionalInfo = device.getAdditionalInfo();
+    }
+    
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public UUID getCustomerId() {
+        return customerId;
+    }
+
+    public void setCustomerId(UUID customerId) {
+        this.customerId = customerId;
+    }
+    
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public JsonNode getAdditionalInfo() {
+        return additionalInfo;
+    }
+
+    public void setAdditionalInfo(JsonNode additionalInfo) {
+        this.additionalInfo = additionalInfo;
+    }
+    
+    @Override
+    public String getSearchTextSource() {
+        return name;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+    
+    public String getSearchText() {
+        return searchText;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode());
+        result = prime * result + ((customerId == null) ? 0 : customerId.hashCode());
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        DeviceEntity other = (DeviceEntity) obj;
+        if (additionalInfo == null) {
+            if (other.additionalInfo != null)
+                return false;
+        } else if (!additionalInfo.equals(other.additionalInfo))
+            return false;
+        if (customerId == null) {
+            if (other.customerId != null)
+                return false;
+        } else if (!customerId.equals(other.customerId))
+            return false;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        if (tenantId == null) {
+            if (other.tenantId != null)
+                return false;
+        } else if (!tenantId.equals(other.tenantId))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("DeviceEntity [id=");
+        builder.append(id);
+        builder.append(", tenantId=");
+        builder.append(tenantId);
+        builder.append(", customerId=");
+        builder.append(customerId);
+        builder.append(", name=");
+        builder.append(name);
+        builder.append(", additionalInfo=");
+        builder.append(additionalInfo);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public Device toData() {
+        Device device = new Device(new DeviceId(id));
+        device.setCreatedTime(UUIDs.unixTimestamp(id));
+        if (tenantId != null) {
+            device.setTenantId(new TenantId(tenantId));
+        }
+        if (customerId != null) {
+            device.setCustomerId(new CustomerId(customerId));
+        }
+        device.setName(name);
+        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
new file mode 100644
index 0000000..4618f42
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
@@ -0,0 +1,119 @@
+/**
+ * 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.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.fasterxml.jackson.databind.JsonNode;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+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.model.ModelConstants;
+
+import java.util.UUID;
+
+@Data
+@NoArgsConstructor
+@Entity
+@Table(name = ModelConstants.DEVICE_COLUMN_FAMILY_NAME)
+public class EventEntity implements BaseEntity<Event> {
+
+    @Transient
+    private static final long serialVersionUID = -5717830061727466727L;
+
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+
+    @Id
+    @Column(name = ModelConstants.EVENT_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @Column(name = ModelConstants.EVENT_ENTITY_TYPE_PROPERTY)
+    private EntityType entityType;
+
+    @Column(name = ModelConstants.EVENT_ENTITY_ID_PROPERTY)
+    private UUID entityId;
+
+    @Column(name = ModelConstants.EVENT_TYPE_PROPERTY)
+    private String eventType;
+
+    @Column(name = ModelConstants.EVENT_UID_PROPERTY)
+    private String eventUId;
+
+    @Column(name = ModelConstants.EVENT_BODY_PROPERTY)
+    private JsonNode body;
+
+    public EventEntity(Event event) {
+        if (event.getId() != null) {
+            this.id = event.getId().getId();
+        }
+        if (event.getTenantId() != null) {
+            this.tenantId = event.getTenantId().getId();
+        }
+        if (event.getEntityId() != null) {
+            this.entityType = event.getEntityId().getEntityType();
+            this.entityId = event.getEntityId().getId();
+        }
+        this.eventType = event.getType();
+        this.eventUId = event.getUid();
+        this.body = event.getBody();
+    }
+
+    @Override
+    public UUID getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    @Override
+    public Event toData() {
+        Event event = new Event(new EventId(id));
+        event.setCreatedTime(UUIDs.unixTimestamp(id));
+        event.setTenantId(new TenantId(tenantId));
+        switch (entityType) {
+            case TENANT:
+                event.setEntityId(new TenantId(entityId));
+                break;
+            case DEVICE:
+                event.setEntityId(new DeviceId(entityId));
+                break;
+            case CUSTOMER:
+                event.setEntityId(new CustomerId(entityId));
+                break;
+            case RULE:
+                event.setEntityId(new RuleId(entityId));
+                break;
+            case PLUGIN:
+                event.setEntityId(new PluginId(entityId));
+                break;
+        }
+        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
new file mode 100644
index 0000000..fc58f90
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java
@@ -0,0 +1,216 @@
+/**
+ * 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.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.fasterxml.jackson.databind.JsonNode;
+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 java.util.Objects;
+import java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.PLUGIN_COLUMN_FAMILY_NAME)
+public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
+
+    @Transient
+    private static final long serialVersionUID = -6164321050824823149L;
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+
+    @Column(name = ModelConstants.PLUGIN_API_TOKEN_PROPERTY)
+    private String apiToken;
+
+    @Column(name = ModelConstants.PLUGIN_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @Column(name = ModelConstants.PLUGIN_NAME_PROPERTY)
+    private String name;
+
+    @Column(name = ModelConstants.PLUGIN_CLASS_PROPERTY)
+    private String clazz;
+
+    @Column(name = ModelConstants.PLUGIN_ACCESS_PROPERTY)
+    private boolean publicAccess;
+
+    @Column(name = ModelConstants.PLUGIN_STATE_PROPERTY)
+    private ComponentLifecycleState state;
+
+    @Column(name = ModelConstants.PLUGIN_CONFIGURATION_PROPERTY)
+    private JsonNode configuration;
+
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+
+    @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY)
+    private JsonNode additionalInfo;
+
+    public PluginMetaDataEntity() {
+    }
+
+    public PluginMetaDataEntity(PluginMetaData pluginMetaData) {
+        if (pluginMetaData.getId() != null) {
+            this.id = pluginMetaData.getId().getId();
+        }
+        this.tenantId = pluginMetaData.getTenantId().getId();
+        this.apiToken = pluginMetaData.getApiToken();
+        this.clazz = pluginMetaData.getClazz();
+        this.name = pluginMetaData.getName();
+        this.publicAccess = pluginMetaData.isPublicAccess();
+        this.state = pluginMetaData.getState();
+        this.configuration = pluginMetaData.getConfiguration();
+        this.searchText = pluginMetaData.getName();
+        this.additionalInfo = pluginMetaData.getAdditionalInfo();
+    }
+
+    @Override
+    public String getSearchTextSource() {
+        return searchText;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+
+    @Override
+    public UUID getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public String getApiToken() {
+        return apiToken;
+    }
+
+    public void setApiToken(String apiToken) {
+        this.apiToken = apiToken;
+    }
+
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getClazz() {
+        return clazz;
+    }
+
+    public void setClazz(String clazz) {
+        this.clazz = clazz;
+    }
+
+    public JsonNode getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(JsonNode configuration) {
+        this.configuration = configuration;
+    }
+
+    public boolean isPublicAccess() {
+        return publicAccess;
+    }
+
+    public void setPublicAccess(boolean publicAccess) {
+        this.publicAccess = publicAccess;
+    }
+
+    public ComponentLifecycleState getState() {
+        return state;
+    }
+
+    public void setState(ComponentLifecycleState state) {
+        this.state = state;
+    }
+
+    public String getSearchText() {
+        return searchText;
+    }
+
+    public JsonNode getAdditionalInfo() {
+        return additionalInfo;
+    }
+
+    public void setAdditionalInfo(JsonNode additionalInfo) {
+        this.additionalInfo = additionalInfo;
+    }
+
+    @Override
+    public PluginMetaData toData() {
+        PluginMetaData data = new PluginMetaData(new PluginId(id));
+        data.setTenantId(new TenantId(tenantId));
+        data.setCreatedTime(UUIDs.unixTimestamp(id));
+        data.setName(name);
+        data.setConfiguration(configuration);
+        data.setClazz(clazz);
+        data.setPublicAccess(publicAccess);
+        data.setState(state);
+        data.setApiToken(apiToken);
+        data.setAdditionalInfo(additionalInfo);
+        return data;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        PluginMetaDataEntity entity = (PluginMetaDataEntity) o;
+        return Objects.equals(id, entity.id) && Objects.equals(apiToken, entity.apiToken) && Objects.equals(tenantId, entity.tenantId)
+                && Objects.equals(name, entity.name) && Objects.equals(clazz, entity.clazz) && Objects.equals(state, entity.state)
+                && Objects.equals(configuration, entity.configuration)
+                && Objects.equals(searchText, entity.searchText);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, apiToken, tenantId, name, clazz, state, configuration, searchText);
+    }
+
+    @Override
+    public String toString() {
+        return "PluginMetaDataEntity{" + "id=" + id + ", apiToken='" + apiToken + '\'' + ", tenantId=" + tenantId + ", name='" + name + '\'' + ", clazz='"
+                + clazz + '\'' + ", state=" + state + ", configuration=" + configuration + ", searchText='" + searchText + '\'' + '}';
+    }
+}
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
new file mode 100644
index 0000000..506b74a
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java
@@ -0,0 +1,228 @@
+/**
+ * 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.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.fasterxml.jackson.databind.JsonNode;
+import org.thingsboard.server.common.data.id.RuleId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
+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 java.util.Objects;
+import java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.RULE_COLUMN_FAMILY_NAME)
+public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
+
+    @Transient
+    private static final long serialVersionUID = -1506905644259463884L;
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+    @Column(name = ModelConstants.RULE_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+    @Column(name = ModelConstants.RULE_NAME_PROPERTY)
+    private String name;
+    @Column(name = ModelConstants.RULE_STATE_PROPERTY)
+    private ComponentLifecycleState state;
+    @Column(name = ModelConstants.RULE_WEIGHT_PROPERTY)
+    private int weight;
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+    @Column(name = ModelConstants.RULE_PLUGIN_TOKEN_PROPERTY)
+    private String pluginToken;
+    @Column(name = ModelConstants.RULE_FILTERS)
+    private JsonNode filters;
+    @Column(name = ModelConstants.RULE_PROCESSOR)
+    private JsonNode processor;
+    @Column(name = ModelConstants.RULE_ACTION)
+    private JsonNode action;
+    @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY)
+    private JsonNode additionalInfo;
+
+    public RuleMetaDataEntity() {
+    }
+
+    public RuleMetaDataEntity(RuleMetaData rule) {
+        if (rule.getId() != null) {
+            this.id = rule.getUuidId();
+        }
+        this.tenantId = DaoUtil.getId(rule.getTenantId());
+        this.name = rule.getName();
+        this.pluginToken = rule.getPluginToken();
+        this.state = rule.getState();
+        this.weight = rule.getWeight();
+        this.searchText = rule.getName();
+        this.filters = rule.getFilters();
+        this.processor = rule.getProcessor();
+        this.action = rule.getAction();
+        this.additionalInfo = rule.getAdditionalInfo();
+    }
+
+    @Override
+    public String getSearchTextSource() {
+        return searchText;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+
+    @Override
+    public UUID getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public ComponentLifecycleState getState() {
+        return state;
+    }
+
+    public void setState(ComponentLifecycleState state) {
+        this.state = state;
+    }
+
+    public int getWeight() {
+        return weight;
+    }
+
+    public void setWeight(int weight) {
+        this.weight = weight;
+    }
+
+    public String getPluginToken() {
+        return pluginToken;
+    }
+
+    public void setPluginToken(String pluginToken) {
+        this.pluginToken = pluginToken;
+    }
+
+    public String getSearchText() {
+        return searchText;
+    }
+
+    public JsonNode getFilters() {
+        return filters;
+    }
+
+    public void setFilters(JsonNode filters) {
+        this.filters = filters;
+    }
+
+    public JsonNode getProcessor() {
+        return processor;
+    }
+
+    public void setProcessor(JsonNode processor) {
+        this.processor = processor;
+    }
+
+    public JsonNode getAction() {
+        return action;
+    }
+
+    public void setAction(JsonNode action) {
+        this.action = action;
+    }
+
+    public JsonNode getAdditionalInfo() {
+        return additionalInfo;
+    }
+
+    public void setAdditionalInfo(JsonNode additionalInfo) {
+        this.additionalInfo = additionalInfo;
+    }
+
+    @Override
+    public RuleMetaData toData() {
+        RuleMetaData rule = new RuleMetaData(new RuleId(id));
+        rule.setTenantId(new TenantId(tenantId));
+        rule.setName(name);
+        rule.setState(state);
+        rule.setWeight(weight);
+        rule.setCreatedTime(UUIDs.unixTimestamp(id));
+        rule.setPluginToken(pluginToken);
+        rule.setFilters(filters);
+        rule.setProcessor(processor);
+        rule.setAction(action);
+        rule.setAdditionalInfo(additionalInfo);
+        return rule;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        RuleMetaDataEntity that = (RuleMetaDataEntity) o;
+        return weight == that.weight &&
+                Objects.equals(id, that.id) &&
+                Objects.equals(tenantId, that.tenantId) &&
+                Objects.equals(name, that.name) &&
+                Objects.equals(pluginToken, that.pluginToken) &&
+                Objects.equals(state, that.state) &&
+                Objects.equals(searchText, that.searchText);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, tenantId, name, pluginToken, state, weight, searchText);
+    }
+
+    @Override
+    public String toString() {
+        return "RuleMetaDataEntity{" +
+                "id=" + id +
+                ", tenantId=" + tenantId +
+                ", name='" + name + '\'' +
+                ", pluginToken='" + pluginToken + '\'' +
+                ", state='" + state + '\'' +
+                ", weight=" + weight +
+                ", searchText='" + searchText + '\'' +
+                '}';
+    }
+}
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
new file mode 100644
index 0000000..06b6131
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
@@ -0,0 +1,351 @@
+/**
+ * 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.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 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 java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.TENANT_COLUMN_FAMILY_NAME)
+public final class TenantEntity implements SearchTextEntity<Tenant> {
+
+    @Transient
+    private static final long serialVersionUID = -4330655990232136337L;
+
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+
+    @Column(name = ModelConstants.TENANT_TITLE_PROPERTY)
+    private String title;
+    
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+
+    @Column(name = ModelConstants.TENANT_REGION_PROPERTY)
+    private String region;
+    
+    @Column(name = ModelConstants.COUNTRY_PROPERTY)
+    private String country;
+    
+    @Column(name = ModelConstants.STATE_PROPERTY)
+    private String state;
+
+    @Column(name = ModelConstants.CITY_PROPERTY)
+    private String city;
+
+    @Column(name = ModelConstants.ADDRESS_PROPERTY)
+    private String address;
+
+    @Column(name = ModelConstants.ADDRESS2_PROPERTY)
+    private String address2;
+
+    @Column(name = ModelConstants.ZIP_PROPERTY)
+    private String zip;
+
+    @Column(name = ModelConstants.PHONE_PROPERTY)
+    private String phone;
+
+    @Column(name = ModelConstants.EMAIL_PROPERTY)
+    private String email;
+
+    @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY)
+    private JsonNode additionalInfo;
+
+    public TenantEntity() {
+        super();
+    }
+
+    public TenantEntity(Tenant tenant) {
+        if (tenant.getId() != null) {
+            this.id = tenant.getId().getId();
+        }
+        this.title = tenant.getTitle();
+        this.region = tenant.getRegion();
+        this.country = tenant.getCountry();
+        this.state = tenant.getState();
+        this.city = tenant.getCity();
+        this.address = tenant.getAddress();
+        this.address2 = tenant.getAddress2();
+        this.zip = tenant.getZip();
+        this.phone = tenant.getPhone();
+        this.email = tenant.getEmail();
+        this.additionalInfo = tenant.getAdditionalInfo();
+    }
+    
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getRegion() {
+        return region;
+    }
+
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    public String getCountry() {
+        return country;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getAddress2() {
+        return address2;
+    }
+
+    public void setAddress2(String address2) {
+        this.address2 = address2;
+    }
+
+    public String getZip() {
+        return zip;
+    }
+
+    public void setZip(String zip) {
+        this.zip = zip;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public JsonNode getAdditionalInfo() {
+        return additionalInfo;
+    }
+
+    public void setAdditionalInfo(JsonNode additionalInfo) {
+        this.additionalInfo = additionalInfo;
+    }
+
+    @Override
+    public String getSearchTextSource() {
+        return title;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+    
+    public String getSearchText() {
+        return searchText;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode());
+        result = prime * result + ((address == null) ? 0 : address.hashCode());
+        result = prime * result + ((address2 == null) ? 0 : address2.hashCode());
+        result = prime * result + ((city == null) ? 0 : city.hashCode());
+        result = prime * result + ((country == null) ? 0 : country.hashCode());
+        result = prime * result + ((email == null) ? 0 : email.hashCode());
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((phone == null) ? 0 : phone.hashCode());
+        result = prime * result + ((region == null) ? 0 : region.hashCode());
+        result = prime * result + ((state == null) ? 0 : state.hashCode());
+        result = prime * result + ((title == null) ? 0 : title.hashCode());
+        result = prime * result + ((zip == null) ? 0 : zip.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        TenantEntity other = (TenantEntity) obj;
+        if (additionalInfo == null) {
+            if (other.additionalInfo != null)
+                return false;
+        } else if (!additionalInfo.equals(other.additionalInfo))
+            return false;
+        if (address == null) {
+            if (other.address != null)
+                return false;
+        } else if (!address.equals(other.address))
+            return false;
+        if (address2 == null) {
+            if (other.address2 != null)
+                return false;
+        } else if (!address2.equals(other.address2))
+            return false;
+        if (city == null) {
+            if (other.city != null)
+                return false;
+        } else if (!city.equals(other.city))
+            return false;
+        if (country == null) {
+            if (other.country != null)
+                return false;
+        } else if (!country.equals(other.country))
+            return false;
+        if (email == null) {
+            if (other.email != null)
+                return false;
+        } else if (!email.equals(other.email))
+            return false;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        if (phone == null) {
+            if (other.phone != null)
+                return false;
+        } else if (!phone.equals(other.phone))
+            return false;
+        if (region == null) {
+            if (other.region != null)
+                return false;
+        } else if (!region.equals(other.region))
+            return false;
+        if (state == null) {
+            if (other.state != null)
+                return false;
+        } else if (!state.equals(other.state))
+            return false;
+        if (title == null) {
+            if (other.title != null)
+                return false;
+        } else if (!title.equals(other.title))
+            return false;
+        if (zip == null) {
+            if (other.zip != null)
+                return false;
+        } else if (!zip.equals(other.zip))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("TenantEntity [id=");
+        builder.append(id);
+        builder.append(", title=");
+        builder.append(title);
+        builder.append(", region=");
+        builder.append(region);
+        builder.append(", country=");
+        builder.append(country);
+        builder.append(", state=");
+        builder.append(state);
+        builder.append(", city=");
+        builder.append(city);
+        builder.append(", address=");
+        builder.append(address);
+        builder.append(", address2=");
+        builder.append(address2);
+        builder.append(", zip=");
+        builder.append(zip);
+        builder.append(", phone=");
+        builder.append(phone);
+        builder.append(", email=");
+        builder.append(email);
+        builder.append(", additionalInfo=");
+        builder.append(additionalInfo);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public Tenant toData() {
+        Tenant tenant = new Tenant(new TenantId(id));
+        tenant.setCreatedTime(UUIDs.unixTimestamp(id));
+        tenant.setTitle(title);
+        tenant.setRegion(region);
+        tenant.setCountry(country);
+        tenant.setState(state);
+        tenant.setCity(city);
+        tenant.setAddress(address);
+        tenant.setAddress2(address2);
+        tenant.setZip(zip);
+        tenant.setPhone(phone);
+        tenant.setEmail(email);
+        tenant.setAdditionalInfo(additionalInfo);
+        return tenant;
+    }
+
+
+}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java
new file mode 100644
index 0000000..42d4e92
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java
@@ -0,0 +1,189 @@
+/**
+ * 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.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 org.thingsboard.server.common.data.id.UserCredentialsId;
+import org.thingsboard.server.common.data.id.UserId;
+import org.thingsboard.server.common.data.security.UserCredentials;
+import org.thingsboard.server.dao.model.BaseEntity;
+import org.thingsboard.server.dao.model.ModelConstants;
+
+import java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.USER_CREDENTIALS_COLUMN_FAMILY_NAME)
+public final class UserCredentialsEntity implements BaseEntity<UserCredentials> {
+
+    @Transient
+    private static final long serialVersionUID = 1348221414123438374L;
+
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+    
+    @Column(name = ModelConstants.USER_CREDENTIALS_USER_ID_PROPERTY)
+    private UUID userId;
+
+    @Column(name = ModelConstants.USER_CREDENTIALS_ENABLED_PROPERTY)
+    private boolean enabled;
+
+    @Column(name = ModelConstants.USER_CREDENTIALS_PASSWORD_PROPERTY)
+    private String password;
+
+    @Column(name = ModelConstants.USER_CREDENTIALS_ACTIVATE_TOKEN_PROPERTY)
+    private String activateToken;
+
+    @Column(name = ModelConstants.USER_CREDENTIALS_RESET_TOKEN_PROPERTY)
+    private String resetToken;
+
+    public UserCredentialsEntity() {
+        super();
+    }
+
+    public UserCredentialsEntity(UserCredentials userCredentials) {
+        if (userCredentials.getId() != null) {
+            this.id = userCredentials.getId().getId();
+        }
+        if (userCredentials.getUserId() != null) {
+            this.userId = userCredentials.getUserId().getId();
+        }
+        this.enabled = userCredentials.isEnabled();
+        this.password = userCredentials.getPassword();
+        this.activateToken = userCredentials.getActivateToken();
+        this.resetToken = userCredentials.getResetToken();
+    }
+    
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getUserId() {
+        return userId;
+    }
+
+    public void setUserId(UUID userId) {
+        this.userId = userId;
+    }
+    
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getActivateToken() {
+        return activateToken;
+    }
+
+    public void setActivateToken(String activateToken) {
+        this.activateToken = activateToken;
+    }
+
+    public String getResetToken() {
+        return resetToken;
+    }
+
+    public void setResetToken(String resetToken) {
+        this.resetToken = resetToken;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((activateToken == null) ? 0 : activateToken.hashCode());
+        result = prime * result + (enabled ? 1231 : 1237);
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((password == null) ? 0 : password.hashCode());
+        result = prime * result + ((resetToken == null) ? 0 : resetToken.hashCode());
+        result = prime * result + ((userId == null) ? 0 : userId.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        UserCredentialsEntity other = (UserCredentialsEntity) obj;
+        if (activateToken == null) {
+            if (other.activateToken != null)
+                return false;
+        } else if (!activateToken.equals(other.activateToken))
+            return false;
+        if (enabled != other.enabled)
+            return false;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        if (password == null) {
+            if (other.password != null)
+                return false;
+        } else if (!password.equals(other.password))
+            return false;
+        if (resetToken == null) {
+            if (other.resetToken != null)
+                return false;
+        } else if (!resetToken.equals(other.resetToken))
+            return false;
+        if (userId == null) {
+            if (other.userId != null)
+                return false;
+        } else if (!userId.equals(other.userId))
+            return false;
+        return true;
+    }
+
+    @Override
+    public UserCredentials toData() {
+        UserCredentials userCredentials = new UserCredentials(new UserCredentialsId(id));
+        userCredentials.setCreatedTime(UUIDs.unixTimestamp(id));
+        if (userId != null) {
+            userCredentials.setUserId(new UserId(userId));
+        }
+        userCredentials.setEnabled(enabled);
+        userCredentials.setPassword(password);
+        userCredentials.setActivateToken(activateToken);
+        userCredentials.setResetToken(resetToken);
+        return userCredentials;
+    }
+
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..a02341d
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java
@@ -0,0 +1,274 @@
+/**
+ * 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.model.sql;
+
+import com.datastax.driver.core.utils.UUIDs;
+import com.fasterxml.jackson.databind.JsonNode;
+import org.thingsboard.server.common.data.User;
+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.SearchTextEntity;
+import org.thingsboard.server.dao.model.ModelConstants;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import java.util.UUID;
+
+/**
+ * @author Valerii Sosliuk
+ */
+@Entity
+@Table(name= ModelConstants.USER_COLUMN_FAMILY_NAME)
+public class UserEntity implements SearchTextEntity<User> {
+
+    @Transient
+    private static final long serialVersionUID = 4349485207981226785L;
+
+    @Id
+    @Column(name=ModelConstants.ID_PROPERTY)
+    private UUID id;
+
+    @Column(name = ModelConstants.USER_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @Column(name = ModelConstants.USER_CUSTOMER_ID_PROPERTY)
+    private UUID customerId;
+
+    @Column(name = ModelConstants.USER_AUTHORITY_PROPERTY)
+    private Authority authority;
+
+    @Column(name = ModelConstants.USER_EMAIL_PROPERTY)
+    private String email;
+
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+
+    @Column(name = ModelConstants.USER_FIRST_NAME_PROPERTY)
+    private String firstName;
+
+    @Column(name = ModelConstants.USER_LAST_NAME_PROPERTY)
+    private String lastName;
+
+    @Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY)
+    private JsonNode additionalInfo;
+
+    public UserEntity(User user) {
+        if (user.getId() != null) {
+            this.id = user.getId().getId();
+        }
+        this.authority = user.getAuthority();
+        if (user.getTenantId() != null) {
+            this.tenantId = user.getTenantId().getId();
+        }
+        if (user.getCustomerId() != null) {
+            this.customerId = user.getCustomerId().getId();
+        }
+        this.email = user.getEmail();
+        this.firstName = user.getFirstName();
+        this.lastName = user.getLastName();
+        this.additionalInfo = user.getAdditionalInfo();
+    }
+
+    public String getSearchText() {
+        return searchText;
+    }
+
+    @Override
+    public String getSearchTextSource() {
+        return searchText;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+
+    @Override
+    public UUID getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public UUID getCustomerId() {
+        return customerId;
+    }
+
+    public void setCustomerId(UUID customerId) {
+        this.customerId = customerId;
+    }
+
+    public Authority getAuthority() {
+        return authority;
+    }
+
+    public void setAuthority(Authority authority) {
+        this.authority = authority;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public JsonNode getAdditionalInfo() {
+        return additionalInfo;
+    }
+
+    public void setAdditionalInfo(JsonNode additionalInfo) {
+        this.additionalInfo = additionalInfo;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("UserEntity [id=");
+        builder.append(id);
+        builder.append(", authority=");
+        builder.append(authority);
+        builder.append(", tenantId=");
+        builder.append(tenantId);
+        builder.append(", customerId=");
+        builder.append(customerId);
+        builder.append(", email=");
+        builder.append(email);
+        builder.append(", firstName=");
+        builder.append(firstName);
+        builder.append(", lastName=");
+        builder.append(lastName);
+        builder.append(", additionalInfo=");
+        builder.append(additionalInfo);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    @Override
+    public User toData() {
+        User user = new User(new UserId(id));
+        user.setCreatedTime(UUIDs.unixTimestamp(id));
+        user.setAuthority(authority);
+        if (tenantId != null) {
+            user.setTenantId(new TenantId(tenantId));
+        }
+        if (customerId != null) {
+            user.setCustomerId(new CustomerId(customerId));
+        }
+        user.setEmail(email);
+        user.setFirstName(firstName);
+        user.setLastName(lastName);
+        user.setAdditionalInfo(additionalInfo);
+        return user;
+    }
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode());
+        result = prime * result + ((authority == null) ? 0 : authority.hashCode());
+        result = prime * result + ((customerId == null) ? 0 : customerId.hashCode());
+        result = prime * result + ((email == null) ? 0 : email.hashCode());
+        result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
+        result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        UserEntity other = (UserEntity) obj;
+        if (additionalInfo == null) {
+            if (other.additionalInfo != null)
+                return false;
+        } else if (!additionalInfo.equals(other.additionalInfo))
+            return false;
+        if (authority != other.authority)
+            return false;
+        if (customerId == null) {
+            if (other.customerId != null)
+                return false;
+        } else if (!customerId.equals(other.customerId))
+            return false;
+        if (email == null) {
+            if (other.email != null)
+                return false;
+        } else if (!email.equals(other.email))
+            return false;
+        if (firstName == null) {
+            if (other.firstName != null)
+                return false;
+        } else if (!firstName.equals(other.firstName))
+            return false;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        if (lastName == null) {
+            if (other.lastName != null)
+                return false;
+        } else if (!lastName.equals(other.lastName))
+            return false;
+        if (tenantId == null) {
+            if (other.tenantId != null)
+                return false;
+        } else if (!tenantId.equals(other.tenantId))
+            return false;
+        return true;
+    }
+
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java
new file mode 100644
index 0000000..c972709
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java
@@ -0,0 +1,190 @@
+/**
+ * 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.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 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.ModelConstants;
+import org.thingsboard.server.dao.model.SearchTextEntity;
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.WIDGETS_BUNDLE_COLUMN_FAMILY_NAME)
+public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle> {
+
+    @Transient
+    private static final long serialVersionUID = 6897035686422298096L;
+
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+
+    @Column(name = ModelConstants.WIDGETS_BUNDLE_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @Column(name = ModelConstants.WIDGETS_BUNDLE_ALIAS_PROPERTY)
+    private String alias;
+
+    @Column(name = ModelConstants.WIDGETS_BUNDLE_TITLE_PROPERTY)
+    private String title;
+
+    @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
+    private String searchText;
+
+    @Column(name = ModelConstants.WIDGETS_BUNDLE_IMAGE_PROPERTY)
+    private ByteBuffer image;
+
+    public WidgetsBundleEntity() {
+        super();
+    }
+
+    public WidgetsBundleEntity(WidgetsBundle widgetsBundle) {
+        if (widgetsBundle.getId() != null) {
+            this.id = widgetsBundle.getId().getId();
+        }
+        if (widgetsBundle.getTenantId() != null) {
+            this.tenantId = widgetsBundle.getTenantId().getId();
+        }
+        this.alias = widgetsBundle.getAlias();
+        this.title = widgetsBundle.getTitle();
+        if (widgetsBundle.getImage() != null) {
+            this.image = ByteBuffer.wrap(widgetsBundle.getImage());
+        }
+    }
+
+    @Override
+    public UUID getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getAlias() {
+        return alias;
+    }
+
+    public void setAlias(String alias) {
+        this.alias = alias;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public ByteBuffer getImage() {
+        return image;
+    }
+
+    public void setImage(ByteBuffer image) {
+        this.image = image;
+    }
+
+    @Override
+    public String getSearchTextSource() {
+        return title;
+    }
+
+    @Override
+    public void setSearchText(String searchText) {
+        this.searchText = searchText;
+    }
+
+    public String getSearchText() {
+        return searchText;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id != null ? id.hashCode() : 0;
+        result = 31 * result + (tenantId != null ? tenantId.hashCode() : 0);
+        result = 31 * result + (alias != null ? alias.hashCode() : 0);
+        result = 31 * result + (title != null ? title.hashCode() : 0);
+        result = 31 * result + (searchText != null ? searchText.hashCode() : 0);
+        result = 31 * result + (image != null ? image.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        WidgetsBundleEntity that = (WidgetsBundleEntity) o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null) return false;
+        if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) return false;
+        if (alias != null ? !alias.equals(that.alias) : that.alias != null) return false;
+        if (title != null ? !title.equals(that.title) : that.title != null) return false;
+        if (searchText != null ? !searchText.equals(that.searchText) : that.searchText != null) return false;
+        return image != null ? image.equals(that.image) : that.image == null;
+
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("WidgetsBundleEntity{");
+        sb.append("id=").append(id);
+        sb.append(", tenantId=").append(tenantId);
+        sb.append(", alias='").append(alias).append('\'');
+        sb.append(", title='").append(title).append('\'');
+        sb.append(", searchText='").append(searchText).append('\'');
+        sb.append(", image=").append(image);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public WidgetsBundle toData() {
+        WidgetsBundle widgetsBundle = new WidgetsBundle(new WidgetsBundleId(id));
+        widgetsBundle.setCreatedTime(UUIDs.unixTimestamp(id));
+        if (tenantId != null) {
+            widgetsBundle.setTenantId(new TenantId(tenantId));
+        }
+        widgetsBundle.setAlias(alias);
+        widgetsBundle.setTitle(title);
+        if (image != null) {
+            byte[] imageByteArray = new byte[image.remaining()];
+            image.get(imageByteArray);
+            widgetsBundle.setImage(imageByteArray);
+        }
+        return widgetsBundle;
+    }
+}
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
new file mode 100644
index 0000000..6c1b949
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java
@@ -0,0 +1,183 @@
+/**
+ * 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.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 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 java.util.UUID;
+
+@Entity
+@Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME)
+public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
+
+    @Transient
+    private static final long serialVersionUID = -5436279069884988630L;
+
+    @Id
+    @Column(name = ModelConstants.ID_PROPERTY)
+    private UUID id;
+
+    @PartitionKey(value = 1)
+    @Column(name = ModelConstants.WIDGET_TYPE_TENANT_ID_PROPERTY)
+    private UUID tenantId;
+
+    @PartitionKey(value = 2)
+    @Column(name = ModelConstants.WIDGET_TYPE_BUNDLE_ALIAS_PROPERTY)
+    private String bundleAlias;
+
+    @Column(name = ModelConstants.WIDGET_TYPE_ALIAS_PROPERTY)
+    private String alias;
+
+    @Column(name = ModelConstants.WIDGET_TYPE_NAME_PROPERTY)
+    private String name;
+
+    @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY)
+    private JsonNode descriptor;
+
+    public WidgetTypeEntity() {
+        super();
+    }
+
+    public WidgetTypeEntity(WidgetType widgetType) {
+        if (widgetType.getId() != null) {
+            this.id = widgetType.getId().getId();
+        }
+        if (widgetType.getTenantId() != null) {
+            this.tenantId = widgetType.getTenantId().getId();
+        }
+        this.bundleAlias = widgetType.getBundleAlias();
+        this.alias = widgetType.getAlias();
+        this.name = widgetType.getName();
+        this.descriptor = widgetType.getDescriptor();
+    }
+
+    @Override
+    public UUID getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public UUID getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(UUID tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getBundleAlias() {
+        return bundleAlias;
+    }
+
+    public void setBundleAlias(String bundleAlias) {
+        this.bundleAlias = bundleAlias;
+    }
+
+    public String getAlias() {
+        return alias;
+    }
+
+    public void setAlias(String alias) {
+        this.alias = alias;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public JsonNode getDescriptor() {
+        return descriptor;
+    }
+
+    public void setDescriptor(JsonNode descriptor) {
+        this.descriptor = descriptor;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id != null ? id.hashCode() : 0;
+        result = 31 * result + (tenantId != null ? tenantId.hashCode() : 0);
+        result = 31 * result + (bundleAlias != null ? bundleAlias.hashCode() : 0);
+        result = 31 * result + (alias != null ? alias.hashCode() : 0);
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (descriptor != null ? descriptor.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        WidgetTypeEntity that = (WidgetTypeEntity) o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null) return false;
+        if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) return false;
+        if (bundleAlias != null ? !bundleAlias.equals(that.bundleAlias) : that.bundleAlias != null) return false;
+        if (alias != null ? !alias.equals(that.alias) : that.alias != null) return false;
+        if (name != null ? !name.equals(that.name) : that.name != null) return false;
+        return descriptor != null ? descriptor.equals(that.descriptor) : that.descriptor == null;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("WidgetTypeEntity{");
+        sb.append("id=").append(id);
+        sb.append(", tenantId=").append(tenantId);
+        sb.append(", bundleAlias='").append(bundleAlias).append('\'');
+        sb.append(", alias='").append(alias).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", descriptor=").append(descriptor);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public WidgetType toData() {
+        WidgetType widgetType = new WidgetType(new WidgetTypeId(id));
+        widgetType.setCreatedTime(UUIDs.unixTimestamp(id));
+        if (tenantId != null) {
+            widgetType.setTenantId(new TenantId(tenantId));
+        }
+        widgetType.setBundleAlias(bundleAlias);
+        widgetType.setAlias(alias);
+        widgetType.setName(name);
+        widgetType.setDescriptor(descriptor);
+        return widgetType;
+    }
+
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/plugin/CassandraBasePluginDao.java b/dao/src/main/java/org/thingsboard/server/dao/plugin/CassandraBasePluginDao.java
index 054a365..9c196e8 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/plugin/CassandraBasePluginDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/plugin/CassandraBasePluginDao.java
@@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.plugin.PluginMetaData;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
 import org.thingsboard.server.dao.DaoUtil;
 import org.thingsboard.server.dao.model.ModelConstants;
-import org.thingsboard.server.dao.model.PluginMetaDataEntity;
+import org.thingsboard.server.dao.model.nosql.PluginMetaDataEntity;
 
 import java.util.Arrays;
 import java.util.List;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraBaseRuleDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraBaseRuleDao.java
index a750940..8f62baf 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraBaseRuleDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraBaseRuleDao.java
@@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.rule.RuleMetaData;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
 import org.thingsboard.server.dao.DaoUtil;
 import org.thingsboard.server.dao.model.ModelConstants;
-import org.thingsboard.server.dao.model.RuleMetaDataEntity;
+import org.thingsboard.server.dao.model.nosql.RuleMetaDataEntity;
 
 import java.util.Arrays;
 import java.util.List;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/settings/CassandraAdminSettingsDao.java b/dao/src/main/java/org/thingsboard/server/dao/settings/CassandraAdminSettingsDao.java
index c1783bc..adeeed0 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/settings/CassandraAdminSettingsDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/settings/CassandraAdminSettingsDao.java
@@ -21,7 +21,7 @@ import org.springframework.stereotype.Component;
 import org.thingsboard.server.common.data.AdminSettings;
 import org.thingsboard.server.dao.CassandraAbstractModelDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.AdminSettingsEntity;
+import org.thingsboard.server.dao.model.nosql.AdminSettingsEntity;
 
 import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
 import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
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
new file mode 100644
index 0000000..a92e607
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
@@ -0,0 +1,90 @@
+/**
+ * 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.sql;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.ListenableFuture;
+import lombok.extern.slf4j.Slf4j;
+import org.thingsboard.server.dao.Dao;
+import org.thingsboard.server.dao.DaoUtil;
+import org.thingsboard.server.dao.model.BaseEntity;
+import org.thingsboard.server.dao.model.SearchTextEntity;
+import org.thingsboard.server.dao.sql.user.JpaRepository;
+
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author Valerii Sosliuk
+ */
+@Slf4j
+public abstract class JpaAbstractDao<E extends BaseEntity<D>, D> implements Dao<D> {
+
+    protected abstract Class<E> getColumnFamilyClass();
+
+    protected abstract String getColumnFamilyName();
+
+    protected abstract JpaRepository<E, UUID> getCrudRepository();
+
+    protected boolean isSearchTextDao() {
+        return false;
+    }
+
+    @Override
+    public D save(D domain) {
+        E entity;
+        try {
+            entity = getColumnFamilyClass().getConstructor(domain.getClass()).newInstance(domain);
+        } catch (Exception e) {
+            log.error("Can't create entity for domain object {}", domain, e);
+            throw new IllegalArgumentException("Can't create entity for domain object {" + domain + "}", e);
+        } if (isSearchTextDao()) {
+            ((SearchTextEntity) entity).setSearchText(((SearchTextEntity) entity).getSearchTextSource().toLowerCase());
+        }
+        log.debug("Saving entity {}", entity);
+        entity = getCrudRepository().save(entity);
+        return DaoUtil.getData(entity);
+    }
+
+    @Override
+    public D findById(UUID key) {
+        log.debug("Get entity by key {}", key);
+        E entity = getCrudRepository().findOne(key);
+        return DaoUtil.getData(entity);
+    }
+
+    @Override
+    public ListenableFuture<D> findByIdAsync(UUID key) {
+        log.debug("Get entity by key {}", key);
+        org.springframework.util.concurrent.ListenableFuture<E> entityFuture = getCrudRepository().findByIdAsync(key);
+        // TODO: vsosliuk implement
+        return null;
+    }
+
+    @Override
+    public boolean removeById(UUID key) {
+        getCrudRepository().delete(key);
+        log.debug("Remove request: {}", key);
+        return getCrudRepository().equals(key);
+    }
+
+    @Override
+    public List<D> find() {
+        log.debug("Get all entities from column family {}", getColumnFamilyName());
+        List<E> entities = Lists.newArrayList(getCrudRepository().findAll());
+        return DaoUtil.convertDataList(entities);
+    }
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaRepository.java
new file mode 100644
index 0000000..0af2bf8
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaRepository.java
@@ -0,0 +1,31 @@
+/**
+ * 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.sql.user;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.util.concurrent.ListenableFuture;
+
+import java.io.Serializable;
+
+/**
+ * @author Valerii Sosliuk
+ */
+public interface JpaRepository<E, ID extends Serializable> extends CrudRepository<E, ID> {
+
+    @Async
+    ListenableFuture<E> findByIdAsync(ID key);
+}
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
new file mode 100644
index 0000000..8fb14d7
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java
@@ -0,0 +1,52 @@
+/**
+ * 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.sql.user;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+import org.thingsboard.server.common.data.User;
+import org.thingsboard.server.dao.model.ModelConstants;
+import org.thingsboard.server.dao.model.sql.UserEntity;
+import org.thingsboard.server.dao.sql.JpaAbstractDao;
+
+import java.util.UUID;
+
+/**
+ * @author Valerii Sosliuk
+ */
+@Component
+@ConditionalOnProperty(prefix="sql", value="enabled",havingValue = "true", matchIfMissing = false)
+public class JpaUserDao extends JpaAbstractDao<UserEntity, User> {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @Override
+    protected Class<UserEntity> getColumnFamilyClass() {
+        return UserEntity.class;
+    }
+
+    @Override
+    protected String getColumnFamilyName() {
+        return ModelConstants.USER_COLUMN_FAMILY_NAME;
+    }
+
+    @Override
+    protected JpaRepository<UserEntity, UUID> getCrudRepository() {
+        return userRepository;
+    }
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java
new file mode 100644
index 0000000..51364c7
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java
@@ -0,0 +1,26 @@
+/**
+ * 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.sql.user;
+
+import org.thingsboard.server.dao.model.sql.UserEntity;
+
+import java.util.UUID;
+
+/**
+ * @author Valerii Sosliuk
+ */
+public interface UserRepository extends JpaRepository<UserEntity, UUID> {
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/CassandraTenantDao.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/CassandraTenantDao.java
index d4d067e..dfefb75 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/tenant/CassandraTenantDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/CassandraTenantDao.java
@@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.Tenant;
 import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.TenantEntity;
+import org.thingsboard.server.dao.model.nosql.TenantEntity;
 
 import java.util.Arrays;
 import java.util.List;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java
index 71102b1..d58815f 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java
@@ -15,10 +15,6 @@
  */
 package org.thingsboard.server.dao.timeseries;
 
-// CASSANDRA ???
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.ResultSetFuture;
-import com.datastax.driver.core.Row;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesDao.java
index afa5c95..733200d 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesDao.java
@@ -15,9 +15,6 @@
  */
 package org.thingsboard.server.dao.timeseries;
 
-// CASSANDRA ???
-import com.datastax.driver.core.ResultSetFuture;
-import com.datastax.driver.core.Row;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.thingsboard.server.common.data.kv.TsKvEntry;
 import org.thingsboard.server.common.data.kv.TsKvQuery;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesService.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesService.java
index 28ed5dd..b2bf2e0 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesService.java
@@ -15,10 +15,6 @@
  */
 package org.thingsboard.server.dao.timeseries;
 
-// CASSANDRA ???
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.ResultSetFuture;
-import com.datastax.driver.core.Row;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.thingsboard.server.common.data.id.UUIDBased;
 import org.thingsboard.server.common.data.kv.TsKvEntry;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserCredentialsDao.java b/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserCredentialsDao.java
index b44ab6a..22ed06a 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserCredentialsDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserCredentialsDao.java
@@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.security.UserCredentials;
 import org.thingsboard.server.dao.CassandraAbstractModelDao;
 import org.thingsboard.server.dao.DaoUtil;
 import org.thingsboard.server.dao.model.ModelConstants;
-import org.thingsboard.server.dao.model.UserCredentialsEntity;
+import org.thingsboard.server.dao.model.nosql.UserCredentialsEntity;
 
 import java.util.UUID;
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserDao.java b/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserDao.java
index 21ffa35..d09c84c 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserDao.java
@@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.security.Authority;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
 import org.thingsboard.server.dao.DaoUtil;
 import org.thingsboard.server.dao.model.ModelConstants;
-import org.thingsboard.server.dao.model.UserEntity;
+import org.thingsboard.server.dao.model.nosql.UserEntity;
 
 import java.util.Arrays;
 import java.util.List;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/CassandraWidgetsBundleDao.java b/dao/src/main/java/org/thingsboard/server/dao/widget/CassandraWidgetsBundleDao.java
index 036d754..d43d25d 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/widget/CassandraWidgetsBundleDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/widget/CassandraWidgetsBundleDao.java
@@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.common.data.widget.WidgetsBundle;
 import org.thingsboard.server.dao.CassandraAbstractSearchTextDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.WidgetsBundleEntity;
+import org.thingsboard.server.dao.model.nosql.WidgetsBundleEntity;
 
 import java.util.Arrays;
 import java.util.List;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/CassandraWidgetTypeDao.java b/dao/src/main/java/org/thingsboard/server/dao/widget/CassandraWidgetTypeDao.java
index 56e6db9..8c2cae7 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/widget/CassandraWidgetTypeDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/widget/CassandraWidgetTypeDao.java
@@ -21,7 +21,7 @@ import org.springframework.stereotype.Component;
 import org.thingsboard.server.common.data.widget.WidgetType;
 import org.thingsboard.server.dao.CassandraAbstractModelDao;
 import org.thingsboard.server.dao.DaoUtil;
-import org.thingsboard.server.dao.model.WidgetTypeEntity;
+import org.thingsboard.server.dao.model.nosql.WidgetTypeEntity;
 
 import java.util.List;
 import java.util.UUID;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/attributes/BaseAttributesServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/attributes/BaseAttributesServiceTest.java
index 559a313..a9835cb 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/attributes/BaseAttributesServiceTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/attributes/BaseAttributesServiceTest.java
@@ -15,7 +15,6 @@
  */
 package org.thingsboard.server.dao.attributes;
 
-import com.datastax.driver.core.utils.UUIDs;
 import org.thingsboard.server.common.data.DataConstants;
 import org.thingsboard.server.common.data.id.DeviceId;
 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/event/BaseEventServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/event/BaseEventServiceTest.java
index bdabcf4..b185d2c 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/event/BaseEventServiceTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/event/BaseEventServiceTest.java
@@ -15,8 +15,6 @@
  */
 package org.thingsboard.server.dao.event;
 
-import com.datastax.driver.core.utils.UUIDs;
-import org.apache.cassandra.utils.UUIDGen;
 import org.junit.Assert;
 import org.junit.Test;
 import org.thingsboard.server.common.data.DataConstants;
@@ -34,7 +32,6 @@ import java.io.IOException;
 import java.time.LocalDateTime;
 import java.time.Month;
 import java.time.ZoneOffset;
-import java.util.List;
 import java.util.Optional;
 
 public class BaseEventServiceTest extends AbstractServiceTest {
diff --git a/dao/src/test/java/org/thingsboard/server/dao/plugin/BasePluginServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/plugin/BasePluginServiceTest.java
index 4367c87..80acec7 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/plugin/BasePluginServiceTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/plugin/BasePluginServiceTest.java
@@ -15,22 +15,19 @@
  */
 package org.thingsboard.server.dao.plugin;
 
-import java.util.UUID;
-
 import lombok.extern.slf4j.Slf4j;
+import org.junit.Assert;
+import org.junit.Test;
 import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.page.TextPageData;
 import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.common.data.plugin.PluginMetaData;
-import org.thingsboard.server.common.data.rule.RuleMetaData;
+import org.thingsboard.server.dao.model.ModelConstants;
 import org.thingsboard.server.dao.service.AbstractServiceTest;
 import org.junit.Assert;
 import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import com.datastax.driver.core.utils.UUIDs;
-import org.thingsboard.server.dao.model.ModelConstants;
+import java.util.UUID;
 
 @Slf4j
 public class BasePluginServiceTest extends AbstractServiceTest {
diff --git a/dao/src/test/java/org/thingsboard/server/dao/rule/BaseRuleServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/rule/BaseRuleServiceTest.java
index f62f26c..fe40b84 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/rule/BaseRuleServiceTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/rule/BaseRuleServiceTest.java
@@ -15,7 +15,6 @@
  */
 package org.thingsboard.server.dao.rule;
 
-import com.datastax.driver.core.utils.UUIDs;
 import org.junit.Assert;
 import org.junit.Test;
 import org.thingsboard.server.common.data.id.TenantId;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java
index f66e6ee..01de94f 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/AbstractServiceTest.java
@@ -15,7 +15,6 @@
  */
 package org.thingsboard.server.dao.service;
 
-import com.datastax.driver.core.utils.UUIDs;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/CustomerServiceImplTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/CustomerServiceImplTest.java
index fd0b20f..67ff8b0 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/CustomerServiceImplTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/CustomerServiceImplTest.java
@@ -15,23 +15,21 @@
  */
 package org.thingsboard.server.dao.service;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 import org.apache.commons.lang3.RandomStringUtils;
 import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
 import org.thingsboard.server.common.data.Customer;
 import org.thingsboard.server.common.data.Tenant;
 import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.page.TextPageData;
 import org.thingsboard.server.common.data.page.TextPageLink;
 import org.thingsboard.server.dao.exception.DataValidationException;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
 
-import com.datastax.driver.core.utils.UUIDs;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 public class CustomerServiceImplTest extends AbstractServiceTest {
     
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/DashboardServiceImplTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/DashboardServiceImplTest.java
index 949198c..95f9430 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/DashboardServiceImplTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/DashboardServiceImplTest.java
@@ -15,7 +15,6 @@
  */
 package org.thingsboard.server.dao.service;
 
-import com.datastax.driver.core.utils.UUIDs;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.junit.After;
 import org.junit.Assert;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceCredentialsCacheTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceCredentialsCacheTest.java
index 3ccdea3..f9068ed 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceCredentialsCacheTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceCredentialsCacheTest.java
@@ -15,7 +15,6 @@
  */
 package org.thingsboard.server.dao.service;
 
-import com.datastax.driver.core.utils.UUIDs;
 import com.hazelcast.core.HazelcastInstance;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.junit.After;
@@ -39,10 +38,7 @@ import org.thingsboard.server.dao.device.DeviceService;
 
 import java.util.UUID;
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
 
 @TestPropertySource(properties = {"cache.enabled = true"})
 public class DeviceCredentialsCacheTest extends AbstractServiceTest {
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceCredentialsServiceImplTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceCredentialsServiceImplTest.java
index efdab8a..c31fd2b 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceCredentialsServiceImplTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceCredentialsServiceImplTest.java
@@ -15,7 +15,6 @@
  */
 package org.thingsboard.server.dao.service;
 
-import com.datastax.driver.core.utils.UUIDs;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.junit.After;
 import org.junit.Assert;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceImplTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceImplTest.java
index e9113d4..8126bfa 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceImplTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceImplTest.java
@@ -15,7 +15,6 @@
  */
 package org.thingsboard.server.dao.service;
 
-import com.datastax.driver.core.utils.UUIDs;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.junit.After;
 import org.junit.Assert;
@@ -25,8 +24,6 @@ import org.thingsboard.server.common.data.Customer;
 import org.thingsboard.server.common.data.Device;
 import org.thingsboard.server.common.data.Tenant;
 import org.thingsboard.server.common.data.id.CustomerId;
-import org.thingsboard.server.common.data.id.DeviceCredentialsId;
-import org.thingsboard.server.common.data.id.DeviceId;
 import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.page.TextPageData;
 import org.thingsboard.server.common.data.page.TextPageLink;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/WidgetsBundleServiceImplTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/WidgetsBundleServiceImplTest.java
index 6345567..f779462 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/WidgetsBundleServiceImplTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/WidgetsBundleServiceImplTest.java
@@ -15,7 +15,6 @@
  */
 package org.thingsboard.server.dao.service;
 
-import com.datastax.driver.core.utils.UUIDs;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/WidgetTypeServiceImplTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/WidgetTypeServiceImplTest.java
index cf3fd4b..9c5fb64 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/service/WidgetTypeServiceImplTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/service/WidgetTypeServiceImplTest.java
@@ -15,7 +15,6 @@
  */
 package org.thingsboard.server.dao.service;
 
-import com.datastax.driver.core.utils.UUIDs;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.After;
@@ -23,7 +22,6 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.thingsboard.server.common.data.Tenant;
-import org.thingsboard.server.common.data.User;
 import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.widget.WidgetType;
 import org.thingsboard.server.common.data.widget.WidgetsBundle;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/timeseries/TimeseriesServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/timeseries/TimeseriesServiceTest.java
index 134f471..49b77c2 100644
--- a/dao/src/test/java/org/thingsboard/server/dao/timeseries/TimeseriesServiceTest.java
+++ b/dao/src/test/java/org/thingsboard/server/dao/timeseries/TimeseriesServiceTest.java
@@ -15,21 +15,14 @@
  */
 package org.thingsboard.server.dao.timeseries;
 
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.ResultSetFuture;
-import com.datastax.driver.core.utils.UUIDs;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.Assert;
+import org.junit.Test;
 import org.thingsboard.server.common.data.DataConstants;
 import org.thingsboard.server.common.data.id.DeviceId;
-import org.thingsboard.server.dao.service.AbstractServiceTest;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.thingsboard.server.common.data.kv.*;
+import org.thingsboard.server.dao.service.AbstractServiceTest;
 
-import java.time.LocalDateTime;
-import java.time.ZoneOffset;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;

pom.xml 5(+5 -0)

diff --git a/pom.xml b/pom.xml
index 6324712..64017d7 100755
--- a/pom.xml
+++ b/pom.xml
@@ -412,6 +412,11 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-data-jpa</artifactId>
+                <version>${spring-boot.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.springframework</groupId>
                 <artifactId>spring-context</artifactId>
                 <version>${spring.version}</version>