thingsboard-memoizeit

JPA DAO Basic Implementation & Tests

4/22/2017 11:37:51 PM

Changes

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

pom.xml 19(+19 -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 ed75b10..0b9e37c 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
@@ -16,6 +16,9 @@
 package org.thingsboard.server.actors.plugin;
 
 import akka.actor.ActorRef;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.ResultSetFuture;
+import com.datastax.driver.core.Row;
 import com.google.common.base.Function;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;

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

diff --git a/dao/pom.xml b/dao/pom.xml
index 977be95..fddc440 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -66,6 +66,16 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.dbunit</groupId>
+            <artifactId>dbunit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.springtestdbunit</groupId>
+            <artifactId>spring-test-dbunit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-all</artifactId>
             <scope>test</scope>
@@ -154,6 +164,24 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</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 6696f39..ae58d4d 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,6 +15,8 @@
  */
 package org.thingsboard.server.dao.attributes;
 
+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 222ffa3..6bf9fb2 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,12 @@
  */
 package org.thingsboard.server.dao.attributes;
 
+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.DeviceId;
 import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.UUIDBased;
 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
 
 import java.util.Collection;
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 5ed231b..da46119 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,6 +15,8 @@
  */
 package org.thingsboard.server.dao.attributes;
 
+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/JpaDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java
index 167518a..f349baa 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java
@@ -16,27 +16,33 @@
 package org.thingsboard.server.dao;
 
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
 
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
 import javax.sql.DataSource;
 
 /**
  * @author Valerii Sosliuk
  */
 @Configuration
+@EnableAutoConfiguration
 @ConditionalOnProperty(prefix="sql", value="enabled",havingValue = "true", matchIfMissing = false)
+@ComponentScan("org.thingsboard.server.dao.sql")
+@EnableJpaRepositories("org.thingsboard.server.dao.sql")
+@EntityScan("org.thingsboard.server.dao.model.sql")
+@EnableTransactionManagement
 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
index 40580ee..b090d7d 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java
@@ -30,7 +30,7 @@ import java.util.UUID;
 
 import static org.thingsboard.server.dao.model.ModelConstants.*;
 
-@Entity
+//@Entity
 @Table(name = ADMIN_SETTINGS_COLUMN_FAMILY_NAME)
 public final class AdminSettingsEntity implements BaseEntity<AdminSettings> {
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java
index 53bac76..f32a89e 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java
@@ -30,7 +30,10 @@ import org.thingsboard.server.dao.model.SearchTextEntity;
 
 import java.util.UUID;
 
-@Entity
+/**
+ * @author Andrew Shvayka
+ */
+//@Entity
 @Table(name = ModelConstants.COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME)
 public class ComponentDescriptorEntity implements SearchTextEntity<ComponentDescriptor> {
 
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
index bf7404f..b651306 100644
--- 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
@@ -30,7 +30,7 @@ import org.thingsboard.server.dao.model.SearchTextEntity;
 
 import java.util.UUID;
 
-@Entity
+//@Entity
 @Table(name = ModelConstants.CUSTOMER_COLUMN_FAMILY_NAME)
 public final class CustomerEntity implements SearchTextEntity<Customer> {
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java
index 12a12c1..77e12e2 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java
@@ -31,7 +31,7 @@ import org.thingsboard.server.dao.model.SearchTextEntity;
 
 import java.util.UUID;
 
-@Entity
+//@Entity
 @Table(name = ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME)
 public final class DashboardEntity implements SearchTextEntity<Dashboard> {
 
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
index 5fb052b..f0a50f1 100644
--- 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
@@ -30,7 +30,7 @@ import org.thingsboard.server.dao.model.SearchTextEntity;
 
 import java.util.UUID;
 
-@Entity
+//@Entity
 @Table(name = ModelConstants.DASHBOARD_COLUMN_FAMILY_NAME)
 public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> {
 
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
index de43994..56ebc43 100644
--- 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
@@ -30,7 +30,7 @@ import org.thingsboard.server.dao.model.ModelConstants;
 
 import java.util.UUID;
 
-@Entity
+//@Entity
 @Table(name = ModelConstants.DEVICE_CREDENTIALS_COLUMN_FAMILY_NAME)
 public final class DeviceCredentialsEntity implements BaseEntity<DeviceCredentials> {
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
index 72c2dd5..4cab621 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
@@ -31,7 +31,7 @@ import org.thingsboard.server.dao.model.SearchTextEntity;
 
 import java.util.UUID;
 
-@Entity
+//@Entity
 @Table(name = ModelConstants.DEVICE_COLUMN_FAMILY_NAME)
 public final class DeviceEntity implements SearchTextEntity<Device> {
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
index 4618f42..92808ba 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java
@@ -34,7 +34,7 @@ import java.util.UUID;
 
 @Data
 @NoArgsConstructor
-@Entity
+//@Entity
 @Table(name = ModelConstants.DEVICE_COLUMN_FAMILY_NAME)
 public class EventEntity implements BaseEntity<Event> {
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java
index fc58f90..239e51d 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/PluginMetaDataEntity.java
@@ -32,7 +32,7 @@ import org.thingsboard.server.dao.model.SearchTextEntity;
 import java.util.Objects;
 import java.util.UUID;
 
-@Entity
+//@Entity
 @Table(name = ModelConstants.PLUGIN_COLUMN_FAMILY_NAME)
 public class PluginMetaDataEntity implements SearchTextEntity<PluginMetaData> {
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java
index 506b74a..56b8260 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleMetaDataEntity.java
@@ -33,7 +33,7 @@ import org.thingsboard.server.dao.model.SearchTextEntity;
 import java.util.Objects;
 import java.util.UUID;
 
-@Entity
+//@Entity
 @Table(name = ModelConstants.RULE_COLUMN_FAMILY_NAME)
 public class RuleMetaDataEntity implements SearchTextEntity<RuleMetaData> {
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
index 06b6131..8987425 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java
@@ -29,7 +29,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 
 import java.util.UUID;
 
-@Entity
+//@Entity
 @Table(name = ModelConstants.TENANT_COLUMN_FAMILY_NAME)
 public final class TenantEntity implements SearchTextEntity<Tenant> {
 
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
index 42d4e92..b750ece 100644
--- 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
@@ -16,11 +16,14 @@
 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 lombok.Data;
 import org.thingsboard.server.common.data.id.UserCredentialsId;
 import org.thingsboard.server.common.data.id.UserId;
 import org.thingsboard.server.common.data.security.UserCredentials;
@@ -29,18 +32,19 @@ import org.thingsboard.server.dao.model.ModelConstants;
 
 import java.util.UUID;
 
+@Data
 @Entity
 @Table(name = ModelConstants.USER_CREDENTIALS_COLUMN_FAMILY_NAME)
 public final class UserCredentialsEntity implements BaseEntity<UserCredentials> {
 
     @Transient
-    private static final long serialVersionUID = 1348221414123438374L;
+    private static final long serialVersionUID = -3989724854149114846L;
 
     @Id
-    @Column(name = ModelConstants.ID_PROPERTY)
+    @Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "BINARY(16)")
     private UUID id;
-    
-    @Column(name = ModelConstants.USER_CREDENTIALS_USER_ID_PROPERTY)
+
+    @Column(name = ModelConstants.USER_CREDENTIALS_USER_ID_PROPERTY, columnDefinition = "BINARY(16)", unique = true)
     private UUID userId;
 
     @Column(name = ModelConstants.USER_CREDENTIALS_ENABLED_PROPERTY)
@@ -49,10 +53,10 @@ public final class UserCredentialsEntity implements BaseEntity<UserCredentials> 
     @Column(name = ModelConstants.USER_CREDENTIALS_PASSWORD_PROPERTY)
     private String password;
 
-    @Column(name = ModelConstants.USER_CREDENTIALS_ACTIVATE_TOKEN_PROPERTY)
+    @Column(name = ModelConstants.USER_CREDENTIALS_ACTIVATE_TOKEN_PROPERTY, unique = true)
     private String activateToken;
 
-    @Column(name = ModelConstants.USER_CREDENTIALS_RESET_TOKEN_PROPERTY)
+    @Column(name = ModelConstants.USER_CREDENTIALS_RESET_TOKEN_PROPERTY, unique = true)
     private String resetToken;
 
     public UserCredentialsEntity() {
@@ -71,54 +75,6 @@ public final class UserCredentialsEntity implements BaseEntity<UserCredentials> 
         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() {
@@ -186,4 +142,13 @@ public final class UserCredentialsEntity implements BaseEntity<UserCredentials> 
         return userCredentials;
     }
 
+    @Override
+    public UUID getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(UUID id) {
+        this.id = id;
+    }
 }
\ 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
index a02341d..bf006bb 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java
@@ -17,45 +17,44 @@ package org.thingsboard.server.dao.model.sql;
 
 import com.datastax.driver.core.utils.UUIDs;
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.Data;
 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 org.thingsboard.server.dao.model.SearchTextEntity;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Transient;
+import javax.persistence.*;
+import java.io.IOException;
 import java.util.UUID;
 
 /**
- * @author Valerii Sosliuk
+ * Created by Valerii Sosliuk on 4/21/2017.
  */
+@Data
 @Entity
-@Table(name= ModelConstants.USER_COLUMN_FAMILY_NAME)
+@Table(name = ModelConstants.USER_COLUMN_FAMILY_NAME)
 public class UserEntity implements SearchTextEntity<User> {
-
     @Transient
-    private static final long serialVersionUID = 4349485207981226785L;
+    private static final long serialVersionUID = -271106508790582977L;
 
     @Id
-    @Column(name=ModelConstants.ID_PROPERTY)
+    @Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "BINARY(16)")
     private UUID id;
 
-    @Column(name = ModelConstants.USER_TENANT_ID_PROPERTY)
+    @Column(name = ModelConstants.USER_TENANT_ID_PROPERTY, columnDefinition = "BINARY(16)")
     private UUID tenantId;
 
-    @Column(name = ModelConstants.USER_CUSTOMER_ID_PROPERTY)
+    @Column(name = ModelConstants.USER_CUSTOMER_ID_PROPERTY, columnDefinition = "BINARY(16)")
     private UUID customerId;
 
     @Column(name = ModelConstants.USER_AUTHORITY_PROPERTY)
     private Authority authority;
 
-    @Column(name = ModelConstants.USER_EMAIL_PROPERTY)
+    @Column(name = ModelConstants.USER_EMAIL_PROPERTY, unique = true)
     private String email;
 
     @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
@@ -68,7 +67,10 @@ public class UserEntity implements SearchTextEntity<User> {
     private String lastName;
 
     @Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY)
-    private JsonNode additionalInfo;
+    private String additionalInfo;
+
+    public UserEntity() {
+    }
 
     public UserEntity(User user) {
         if (user.getId() != null) {
@@ -84,11 +86,7 @@ public class UserEntity implements SearchTextEntity<User> {
         this.email = user.getEmail();
         this.firstName = user.getFirstName();
         this.lastName = user.getLastName();
-        this.additionalInfo = user.getAdditionalInfo();
-    }
-
-    public String getSearchText() {
-        return searchText;
+        this.additionalInfo = user.getAdditionalInfo().toString();
     }
 
     @Override
@@ -111,62 +109,6 @@ public class UserEntity implements SearchTextEntity<User> {
         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();
@@ -204,9 +146,18 @@ public class UserEntity implements SearchTextEntity<User> {
         user.setEmail(email);
         user.setFirstName(firstName);
         user.setLastName(lastName);
-        user.setAdditionalInfo(additionalInfo);
+        ObjectMapper mapper = new ObjectMapper();
+        if (additionalInfo != null) {
+            try {
+                JsonNode jsonNode = mapper.readTree(additionalInfo);
+                user.setAdditionalInfo(jsonNode);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
         return user;
     }
+
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -270,5 +221,4 @@ public class UserEntity implements SearchTextEntity<User> {
             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
index c972709..92f2e41 100644
--- 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
@@ -22,6 +22,8 @@ import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Table;
 import javax.persistence.Transient;
+
+import lombok.Data;
 import org.thingsboard.server.common.data.id.TenantId;
 import org.thingsboard.server.common.data.id.WidgetsBundleId;
 import org.thingsboard.server.common.data.widget.WidgetsBundle;
@@ -31,6 +33,7 @@ import org.thingsboard.server.dao.model.SearchTextEntity;
 import java.nio.ByteBuffer;
 import java.util.UUID;
 
+@Data
 @Entity
 @Table(name = ModelConstants.WIDGETS_BUNDLE_COLUMN_FAMILY_NAME)
 public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle> {
@@ -39,10 +42,10 @@ public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle
     private static final long serialVersionUID = 6897035686422298096L;
 
     @Id
-    @Column(name = ModelConstants.ID_PROPERTY)
+    @Column(name = ModelConstants.ID_PROPERTY, columnDefinition = "BINARY(16)")
     private UUID id;
 
-    @Column(name = ModelConstants.WIDGETS_BUNDLE_TENANT_ID_PROPERTY)
+    @Column(name = ModelConstants.WIDGETS_BUNDLE_TENANT_ID_PROPERTY, columnDefinition = "BINARY(16)")
     private UUID tenantId;
 
     @Column(name = ModelConstants.WIDGETS_BUNDLE_ALIAS_PROPERTY)
@@ -55,7 +58,7 @@ public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle
     private String searchText;
 
     @Column(name = ModelConstants.WIDGETS_BUNDLE_IMAGE_PROPERTY)
-    private ByteBuffer image;
+    private byte[] image;
 
     public WidgetsBundleEntity() {
         super();
@@ -71,7 +74,7 @@ public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle
         this.alias = widgetsBundle.getAlias();
         this.title = widgetsBundle.getTitle();
         if (widgetsBundle.getImage() != null) {
-            this.image = ByteBuffer.wrap(widgetsBundle.getImage());
+            this.image = widgetsBundle.getImage();
         }
     }
 
@@ -85,38 +88,6 @@ public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle
         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;
@@ -127,10 +98,6 @@ public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle
         this.searchText = searchText;
     }
 
-    public String getSearchText() {
-        return searchText;
-    }
-
     @Override
     public int hashCode() {
         int result = id != null ? id.hashCode() : 0;
@@ -155,7 +122,6 @@ public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle
         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
@@ -180,11 +146,7 @@ public final class WidgetsBundleEntity implements SearchTextEntity<WidgetsBundle
         }
         widgetsBundle.setAlias(alias);
         widgetsBundle.setTitle(title);
-        if (image != null) {
-            byte[] imageByteArray = new byte[image.remaining()];
-            image.get(imageByteArray);
-            widgetsBundle.setImage(imageByteArray);
-        }
+        widgetsBundle.setImage(image);
         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
index 6c1b949..2c84f72 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java
@@ -32,7 +32,7 @@ import org.thingsboard.server.dao.model.ModelConstants;
 
 import java.util.UUID;
 
-@Entity
+//@Entity
 @Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME)
 public final class WidgetTypeEntity implements BaseEntity<WidgetType> {
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
index 408c4f3..f38f49e 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java
@@ -18,11 +18,11 @@ 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.springframework.data.repository.CrudRepository;
 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;
@@ -37,7 +37,7 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D> implements Dao<
 
     protected abstract String getColumnFamilyName();
 
-    protected abstract JpaRepository<E, UUID> getCrudRepository();
+    protected abstract CrudRepository<E, UUID> getCrudRepository();
 
     protected boolean isSearchTextDao() {
         return false;
@@ -69,7 +69,7 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D> implements Dao<
     @Override
     public ListenableFuture<D> findByIdAsync(UUID key) {
         log.debug("Get entity by key {}", key);
-        org.springframework.util.concurrent.ListenableFuture<E> entityFuture = getCrudRepository().findByIdAsync(key);
+       // org.springframework.util.concurrent.ListenableFuture<E> entityFuture = getCrudRepository().findByIdAsync(key);
         // TODO: vsosliuk implement
         return null;
     }
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java
new file mode 100644
index 0000000..fa119b6
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDao.java
@@ -0,0 +1,71 @@
+/**
+ * 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.data.repository.CrudRepository;
+import org.springframework.stereotype.Component;
+import org.thingsboard.server.common.data.User;
+import org.thingsboard.server.common.data.security.UserCredentials;
+import org.thingsboard.server.dao.DaoUtil;
+import org.thingsboard.server.dao.model.ModelConstants;
+import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
+import org.thingsboard.server.dao.sql.JpaAbstractDao;
+import org.thingsboard.server.dao.user.UserCredentialsDao;
+
+import java.util.UUID;
+
+/**
+ * Created by Valerii Sosliuk on 4/22/2017.
+ */
+@Component
+@ConditionalOnProperty(prefix="sql", value="enabled",havingValue = "true", matchIfMissing = false)
+public class JpaUserCredentialsDao extends JpaAbstractDao<UserCredentialsEntity, UserCredentials> implements UserCredentialsDao {
+
+    @Autowired
+    private UserCredentialsRepository userCredentialsRepository;
+
+    @Override
+    protected Class<UserCredentialsEntity> getEntityClass() {
+        return UserCredentialsEntity.class;
+    }
+
+    @Override
+    protected String getColumnFamilyName() {
+        return ModelConstants.USER_CREDENTIALS_COLUMN_FAMILY_NAME;
+    }
+
+    @Override
+    protected CrudRepository<UserCredentialsEntity, UUID> getCrudRepository() {
+        return userCredentialsRepository;
+    }
+
+    @Override
+    public UserCredentials findByUserId(UUID userId) {
+        return DaoUtil.getData(userCredentialsRepository.findByUserId(userId));
+    }
+
+    @Override
+    public UserCredentials findByActivateToken(String activateToken) {
+        return DaoUtil.getData(userCredentialsRepository.findByActivateToken(activateToken));
+    }
+
+    @Override
+    public UserCredentials findByResetToken(String resetToken) {
+        return DaoUtil.getData(userCredentialsRepository.findByResetToken(resetToken));
+    }
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java
index 551f658..662dbee 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.sql.user;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.data.repository.CrudRepository;
 import org.springframework.stereotype.Component;
 import org.thingsboard.server.common.data.User;
 import org.thingsboard.server.common.data.page.TextPageLink;
@@ -50,7 +51,7 @@ public class JpaUserDao extends JpaAbstractDao<UserEntity, User> implements User
     }
 
     @Override
-    protected JpaRepository<UserEntity, UUID> getCrudRepository() {
+    protected CrudRepository<UserEntity, UUID> getCrudRepository() {
         return userRepository;
     }
 
@@ -61,11 +62,11 @@ public class JpaUserDao extends JpaAbstractDao<UserEntity, User> implements User
 
     @Override
     public List<User> findTenantAdmins(UUID tenantId, TextPageLink pageLink) {
-        return null;
+        throw new RuntimeException("Not Implemented");
     }
 
     @Override
     public List<User> findCustomerUsers(UUID tenantId, UUID customerId, TextPageLink pageLink) {
-        return null;
+        throw new RuntimeException("Not Implemented");
     }
 }
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
index a3bcfa6..aec4137 100644
--- 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
@@ -15,17 +15,17 @@
  */
 package org.thingsboard.server.dao.sql.user;
 
-import org.thingsboard.server.common.data.User;
-import org.thingsboard.server.common.data.page.TextPageLink;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.data.repository.CrudRepository;
 import org.thingsboard.server.dao.model.sql.UserEntity;
 
-import java.util.List;
 import java.util.UUID;
 
 /**
  * @author Valerii Sosliuk
  */
-public interface UserRepository extends JpaRepository<UserEntity, UUID> {
+@ConditionalOnProperty(prefix="sql", value="enabled",havingValue = "true", matchIfMissing = false)
+public interface UserRepository extends CrudRepository<UserEntity, UUID> {
 
     UserEntity findByEmail(String email);
 
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java
new file mode 100644
index 0000000..afa409a
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDao.java
@@ -0,0 +1,91 @@
+/**
+ * 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.widget;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Component;
+import org.thingsboard.server.common.data.page.TextPageLink;
+import org.thingsboard.server.common.data.widget.WidgetsBundle;
+import org.thingsboard.server.dao.DaoUtil;
+import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity;
+import org.thingsboard.server.dao.sql.JpaAbstractDao;
+import org.thingsboard.server.dao.widget.WidgetsBundleDao;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.thingsboard.server.dao.model.ModelConstants.WIDGETS_BUNDLE_COLUMN_FAMILY_NAME;
+
+/**
+ * Created by Valerii Sosliuk on 4/23/2017.
+ */
+@Component
+public class JpaWidgetsBundleDao extends JpaAbstractDao<WidgetsBundleEntity, WidgetsBundle> implements WidgetsBundleDao {
+
+    @Autowired
+    private WidgetsBundleRepository widgetsBundleRepository;
+
+    @Override
+    protected Class<WidgetsBundleEntity> getEntityClass() {
+        return WidgetsBundleEntity.class;
+    }
+
+    @Override
+    protected String getColumnFamilyName() {
+        return WIDGETS_BUNDLE_COLUMN_FAMILY_NAME;
+    }
+
+    @Override
+    protected CrudRepository<WidgetsBundleEntity, UUID> getCrudRepository() {
+        return widgetsBundleRepository;
+    }
+
+    @Override
+    public WidgetsBundle findWidgetsBundleByTenantIdAndAlias(UUID tenantId, String alias) {
+        return DaoUtil.getData(widgetsBundleRepository.findWidgetsBundleByTenantIdAndAlias(tenantId, alias));
+    }
+
+    @Override
+    public List<WidgetsBundle> findSystemWidgetsBundles(TextPageLink pageLink) {
+        if (pageLink.getIdOffset() == null) {
+            return DaoUtil.convertDataList(widgetsBundleRepository.findSystemWidgetsBundlesFirstPage(pageLink.getLimit()
+                    , pageLink.getTextSearch()));
+        } else {
+            return DaoUtil.convertDataList(widgetsBundleRepository.findSystemWidgetsBundlesNextPage(pageLink.getLimit()
+                    , pageLink.getTextSearch(), pageLink.getIdOffset()));
+        }
+        //return DaoUtil.convertDataList(widgetsBundleRepository.findBySearchTextStartsWithIgnoreCase(pageLink.getTextSearch().toLowerCase()));
+        //return DaoUtil.convertDataList(widgetsBundleRepository.findBySearchTextStartsWithIgnoreCase(pageLink.getTextSearch().toLowerCase() ,pageable));
+    }
+
+    @Override
+    public List<WidgetsBundle> findTenantWidgetsBundlesByTenantId(UUID tenantId, TextPageLink pageLink) {
+        throw new RuntimeException("Not implemented");
+    }
+
+    @Override
+    public List<WidgetsBundle> findAllTenantWidgetsBundlesByTenantId(UUID tenantId, TextPageLink pageLink) {
+        throw new RuntimeException("Not implemented");
+    }
+
+    @Override
+    protected boolean isSearchTextDao() {
+        return true;
+    }
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetsBundleRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetsBundleRepository.java
new file mode 100644
index 0000000..ac163df
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetsBundleRepository.java
@@ -0,0 +1,50 @@
+/**
+ * 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.widget;
+
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.query.Param;
+import org.thingsboard.server.common.data.page.TextPageLink;
+import org.thingsboard.server.dao.model.ToData;
+import org.thingsboard.server.dao.model.sql.WidgetsBundleEntity;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Created by Valerii Sosliuk on 4/23/2017.
+ */
+//public interface WidgetsBundleRepository extends CrudRepository<WidgetsBundleEntity, UUID> {
+public interface WidgetsBundleRepository extends JpaRepository<WidgetsBundleEntity, UUID>, JpaSpecificationExecutor {
+
+    WidgetsBundleEntity findWidgetsBundleByTenantIdAndAlias(UUID tenantId, String alias);
+
+    @Query(nativeQuery = true, value = "SELECT * FROM WIDGETS_BUNDLE WHERE TENANT_ID IS NULL " +
+            "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?2, '%')) " +
+            "ORDER BY ID LIMIT ?1")
+    List<WidgetsBundleEntity> findSystemWidgetsBundlesFirstPage(Integer limit, String searchText);
+
+    @Query(nativeQuery = true, value = "SELECT * FROM WIDGETS_BUNDLE WHERE TENANT_ID IS NULL " +
+            "AND LOWER(SEARCH_TEXT) LIKE LOWER(CONCAT(?2, '%')) " +
+            "AND ID > ?3 ORDER BY ID LIMIT ?1")
+    List<WidgetsBundleEntity> findSystemWidgetsBundlesNextPage(Integer limit, String searchText, UUID idOffset);
+
+}
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 d58815f..7a59dcc 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,6 +15,9 @@
  */
 package org.thingsboard.server.dao.timeseries;
 
+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 733200d..452eb2c 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,6 +15,8 @@
  */
 package org.thingsboard.server.dao.timeseries;
 
+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 b2bf2e0..20731b2 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,6 +15,9 @@
  */
 package org.thingsboard.server.dao.timeseries;
 
+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/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java
new file mode 100644
index 0000000..e610245
--- /dev/null
+++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java
@@ -0,0 +1,39 @@
+/**
+ * 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 com.github.springtestdbunit.DbUnitTestExecutionListener;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestExecutionListeners;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
+import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
+
+/**
+ * Created by Valerii Sosliuk on 4/22/2017.
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = {JpaDaoConfig.class})
+@TestPropertySource("classpath:jpa-test.properties")
+@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
+        DirtiesContextTestExecutionListener.class,
+        DbUnitTestExecutionListener.class })
+public class AbstractJpaDaoTest extends AbstractTransactionalJUnit4SpringContextTests {
+
+}
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 a9835cb..559a313 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,6 +15,7 @@
  */
 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 b185d2c..e2c473f 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,6 +15,7 @@
  */
 package org.thingsboard.server.dao.event;
 
+import com.datastax.driver.core.utils.UUIDs;
 import org.junit.Assert;
 import org.junit.Test;
 import org.thingsboard.server.common.data.DataConstants;
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 80acec7..7c0291c 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,6 +15,7 @@
  */
 package org.thingsboard.server.dao.plugin;
 
+import com.datastax.driver.core.utils.UUIDs;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.Assert;
 import org.junit.Test;
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 fe40b84..f62f26c 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,6 +15,7 @@
  */
 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 01de94f..f66e6ee 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,6 +15,7 @@
  */
 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 67ff8b0..0271cad 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,6 +15,7 @@
  */
 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/DashboardServiceImplTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/DashboardServiceImplTest.java
index 95f9430..949198c 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,6 +15,7 @@
  */
 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 f9068ed..4428d02 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,6 +15,7 @@
  */
 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;
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 c31fd2b..efdab8a 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,6 +15,7 @@
  */
 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 8126bfa..b256daa 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,6 +15,7 @@
  */
 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/WidgetsBundleServiceImplTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/WidgetsBundleServiceImplTest.java
index f779462..6345567 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,6 +15,7 @@
  */
 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 9c5fb64..8f0a9f7 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,6 +15,7 @@
  */
 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;
diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDaoTest.java
new file mode 100644
index 0000000..8c75401
--- /dev/null
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserCredentialsDaoTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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 com.github.springtestdbunit.annotation.DatabaseSetup;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.thingsboard.server.common.data.security.UserCredentials;
+import org.thingsboard.server.dao.AbstractJpaDaoTest;
+import org.thingsboard.server.dao.user.UserCredentialsDao;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Created by Valerii Sosliuk on 4/22/2017.
+ */
+public class JpaUserCredentialsDaoTest extends AbstractJpaDaoTest {
+
+    @Autowired
+    private UserCredentialsDao userCredentialsDao;
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/user_credentials.xml")
+    public void testFindAll() {
+        List<UserCredentials> userCredentials = userCredentialsDao.find();
+        assertEquals(2, userCredentials.size());
+    }
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/user_credentials.xml")
+    public void testFindByUserId() {
+        UserCredentials userCredentials = userCredentialsDao.findByUserId(UUID.fromString("787827e6-27d7-11e7-93ae-92361f002671"));
+        assertNotNull(userCredentials);
+        assertEquals("4b9e010c-27d5-11e7-93ae-92361f002671", userCredentials.getId().toString());
+        assertEquals(true, userCredentials.isEnabled());
+        assertEquals("password", userCredentials.getPassword());
+        assertEquals("ACTIVATE_TOKEN_2", userCredentials.getActivateToken());
+        assertEquals("RESET_TOKEN_2", userCredentials.getResetToken());
+    }
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/user_credentials.xml")
+    public void testFindByActivateToken() {
+        UserCredentials userCredentials = userCredentialsDao.findByActivateToken("ACTIVATE_TOKEN_1");
+        assertNotNull(userCredentials);
+        assertEquals("3ed10af0-27d5-11e7-93ae-92361f002671", userCredentials.getId().toString());
+    }
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/user_credentials.xml")
+    public void testFindByResetToken() {
+        UserCredentials userCredentials = userCredentialsDao.findByResetToken("RESET_TOKEN_2");
+        assertNotNull(userCredentials);
+        assertEquals("4b9e010c-27d5-11e7-93ae-92361f002671", userCredentials.getId().toString());
+    }
+}
diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserDaoTest.java
new file mode 100644
index 0000000..5bd254f
--- /dev/null
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/user/JpaUserDaoTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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 com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.springtestdbunit.annotation.DatabaseSetup;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+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.AbstractJpaDaoTest;
+import org.thingsboard.server.dao.user.UserDao;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.UUID;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by Valerii Sosliuk on 4/18/2017.
+ */
+public class JpaUserDaoTest extends AbstractJpaDaoTest {
+
+    @Autowired
+    private UserDao userDao;
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/users.xml")
+    public void testFindAll() {
+        List<User> users = userDao.find();
+        assertEquals(users.size(), 5);
+    }
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/users.xml")
+    public void findByEmail() {
+        User user = userDao.findByEmail("sysadm@thingsboard.org");
+        assertNotNull("User is expected to be not null", user);
+        assertEquals("9cb58ba0-27c1-11e7-93ae-92361f002671", user.getId().toString());
+        assertEquals("c97ea14e-27c1-11e7-93ae-92361f002671", user.getTenantId().toString());
+        assertEquals("cdf9c79e-27c1-11e7-93ae-92361f002671", user.getCustomerId().toString());
+        assertEquals(Authority.SYS_ADMIN, user.getAuthority());
+        assertEquals("John", user.getFirstName());
+        assertEquals("Doe", user.getLastName());
+        assertEquals("{\"key\":\"value-0\"}", user.getAdditionalInfo().toString());
+    }
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/users.xml")
+    public void testSave() throws IOException {
+        User user = new User();
+        user.setId(new UserId(UUID.fromString("cd481534-27cc-11e7-93ae-92361f002671")));
+        user.setTenantId(new TenantId(UUID.fromString("1edcb2c6-27cb-11e7-93ae-92361f002671")));
+        user.setCustomerId(new CustomerId(UUID.fromString("51477cb4-27cb-11e7-93ae-92361f002671")));
+        user.setEmail("user@thingsboard.org");
+        user.setFirstName("Jackson");
+        user.setLastName("Roberts");
+        ObjectMapper mapper = new ObjectMapper();
+        String additionalInfo = "{\"key\":\"value-100\"}";
+        JsonNode jsonNode = mapper.readTree(additionalInfo);
+        user.setAdditionalInfo(jsonNode);
+        userDao.save(user);
+        assertEquals(6, userDao.find().size());
+        User savedUser = userDao.findByEmail("user@thingsboard.org");
+        assertNotNull(savedUser);
+    }
+}
diff --git a/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java
new file mode 100644
index 0000000..4fcf7cb
--- /dev/null
+++ b/dao/src/test/java/org/thingsboard/server/dao/sql/widget/JpaWidgetsBundleDaoTest.java
@@ -0,0 +1,82 @@
+/**
+ * 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.widget;
+
+import com.datastax.driver.core.utils.UUIDs;
+import com.github.springtestdbunit.annotation.DatabaseSetup;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.thingsboard.server.common.data.id.WidgetsBundleId;
+import org.thingsboard.server.common.data.page.TextPageLink;
+import org.thingsboard.server.common.data.widget.WidgetsBundle;
+import org.thingsboard.server.dao.AbstractJpaDaoTest;
+import org.thingsboard.server.dao.widget.WidgetsBundleDao;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by Valerii Sosliuk on 4/23/2017.
+ */
+public class JpaWidgetsBundleDaoTest extends AbstractJpaDaoTest {
+
+    @Autowired
+    private WidgetsBundleDao widgetsBundleDao;
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/widgets_bundle.xml")
+    public void testFindAll() {
+        assertEquals(7, widgetsBundleDao.find().size());
+    }
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/widgets_bundle.xml")
+    public void testFindWidgetsBundleByTenantIdAndAlias() {
+        WidgetsBundle widgetsBundle = widgetsBundleDao.findWidgetsBundleByTenantIdAndAlias(
+                UUID.fromString("250aca8e-2825-11e7-93ae-92361f002671"), "WB3");
+        assertEquals("44e6af4e-2825-11e7-93ae-92361f002671", widgetsBundle.getId().toString());
+    }
+
+    @Test
+    @DatabaseSetup("classpath:dbunit/empty_dataset.xml")
+    public void testFindSystemWidgetsBundles() {
+        for (int i = 0; i < 30; i++) {
+            WidgetsBundle widgetsBundle = new WidgetsBundle();
+            widgetsBundle.setAlias("WB" + i);
+            widgetsBundle.setTitle("WB" + i);
+            widgetsBundle.setId(new WidgetsBundleId(UUIDs.timeBased()));
+            widgetsBundleDao.save(widgetsBundle);
+        }
+        assertEquals(30, widgetsBundleDao.find().size());
+        // Get first page
+        TextPageLink textPageLink1 = new TextPageLink(10, "WB");
+        List<WidgetsBundle> widgetsBundles1 = widgetsBundleDao.findSystemWidgetsBundles(textPageLink1);
+        assertEquals(10, widgetsBundles1.size());
+        for (WidgetsBundle widgetsBundle : widgetsBundles1) {
+            System.out.println(widgetsBundle.getSearchText());
+        }
+        TextPageLink textPageLink2 = new TextPageLink(10, "WB", widgetsBundles1.get(9).getId().getId(), null);
+        List<WidgetsBundle> widgetsBundles2 = widgetsBundleDao.findSystemWidgetsBundles(textPageLink2);
+        assertEquals(10, widgetsBundles1.size());
+        for (WidgetsBundle widgetsBundle : widgetsBundles2) {
+            System.out.println(widgetsBundle.getSearchText());
+        }
+
+    }
+}
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 49b77c2..ae49cb1 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,6 +15,9 @@
  */
 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;
diff --git a/dao/src/test/resources/application-test.properties b/dao/src/test/resources/application-test.properties
index 289f946..1430eb4 100644
--- a/dao/src/test/resources/application-test.properties
+++ b/dao/src/test/resources/application-test.properties
@@ -5,4 +5,6 @@ cache.device_credentials.max_size.policy=PER_NODE
 
 zk.enabled=false
 zk.url=localhost:2181
-zk.zk_dir=/thingsboard
\ No newline at end of file
+zk.zk_dir=/thingsboard
+
+sql.enabled=false
\ No newline at end of file
diff --git a/dao/src/test/resources/dbunit/empty_dataset.xml b/dao/src/test/resources/dbunit/empty_dataset.xml
new file mode 100644
index 0000000..5ed00ba
--- /dev/null
+++ b/dao/src/test/resources/dbunit/empty_dataset.xml
@@ -0,0 +1 @@
+<dataset></dataset>
\ No newline at end of file
diff --git a/dao/src/test/resources/dbunit/user_credentials.xml b/dao/src/test/resources/dbunit/user_credentials.xml
new file mode 100644
index 0000000..c6607e9
--- /dev/null
+++ b/dao/src/test/resources/dbunit/user_credentials.xml
@@ -0,0 +1,28 @@
+<dataset>
+    <user_credentials
+        id="uuid'3ed10af0-27d5-11e7-93ae-92361f002671'"
+        user_id="uuid'44ee8552-27d5-11e7-93ae-92361f002671'"
+        enabled="true"
+        password="password"
+        activate_token="ACTIVATE_TOKEN_1"
+        reset_token="RESET_TOKEN_1"
+    />
+    <user_credentials
+        id="uuid'4b9e010c-27d5-11e7-93ae-92361f002671'"
+        user_id="uuid'787827e6-27d7-11e7-93ae-92361f002671'"
+        enabled="true"
+        password="password"
+        activate_token="ACTIVATE_TOKEN_2"
+        reset_token="RESET_TOKEN_2"
+    />
+    <!--
+    <user_credentials
+        id=""
+        user_id=""
+        enabled="true"
+        password="password"
+        activate_token=""
+        reset_token=""
+    />
+    -->
+</dataset>
\ No newline at end of file
diff --git a/dao/src/test/resources/dbunit/users.xml b/dao/src/test/resources/dbunit/users.xml
new file mode 100644
index 0000000..644a6e9
--- /dev/null
+++ b/dao/src/test/resources/dbunit/users.xml
@@ -0,0 +1,52 @@
+<dataset>
+    <user id="uuid'9cb58ba0-27c1-11e7-93ae-92361f002671'"
+          tenant_id="uuid'c97ea14e-27c1-11e7-93ae-92361f002671'"
+          customer_id="uuid'cdf9c79e-27c1-11e7-93ae-92361f002671'"
+          authority="0"
+          email="sysadm@thingsboard.org"
+          search_text="SYSADM SEARCH TEXT"
+          first_name="John"
+          last_name="Doe"
+          additional_info="{&quot;key&quot;:&quot;value-0&quot;}"
+    />
+    <user id="uuid'1312f328-27c7-11e7-93ae-92361f002671'"
+          tenant_id="uuid'1e1cd4c8-27c7-11e7-93ae-92361f002671'"
+          customer_id="uuid'22fe91e8-27c7-11e7-93ae-92361f002671'"
+          authority="1"
+          email="tenantadm1@thingsboard.org"
+          search_text="TENANTADM1 SEARCH TEXT"
+          first_name="Samuel"
+          last_name="Serif"
+          additional_info="{&quot;key&quot;:&quot;value-11&quot;}"
+    />
+    <user id="uuid'2b090dde-27ca-11e7-93ae-92361f002671'"
+          tenant_id="uuid'1e1cd4c8-27c7-11e7-93ae-92361f002671'"
+          customer_id="uuid'34be535c-27ca-11e7-93ae-92361f002671'"
+          authority="1"
+          email="tenantadm2@thingsboard.org"
+          search_text="TENANTADM2 SEARCH TEXT"
+          first_name="Penny"
+          last_name="Morgan"
+          additional_info="{&quot;key&quot;:&quot;value-12&quot;}"
+    />
+    <user id="uuid'cc8c1ca8-27c7-11e7-93ae-92361f002671'"
+          tenant_id="uuid'd2e27caa-27c7-11e7-93ae-92361f002671'"
+          customer_id="uuid'd89e128a-27c7-11e7-93ae-92361f002671'"
+          authority="2"
+          email="customeruser@thingsboard.org"
+          search_text="CUSTOMER USER SEARCH TEXT"
+          first_name="Norman"
+          last_name="Gordon"
+          additional_info="{&quot;key&quot;:&quot;value-2&quot;}"
+    />
+    <user id="uuid'edb2de58-27c7-11e7-93ae-92361f002671'"
+          tenant_id="uuid'f229675e-27c7-11e7-93ae-92361f002671'"
+          customer_id="uuid'f7a3d4e4-27c7-11e7-93ae-92361f002671'"
+          authority="3"
+          email="refreshtoken@thingsboard.org"
+          search_text="REFRESH TOKEN SEARCH TEXT"
+          first_name="Dianne"
+          last_name="Wensleydale"
+          additional_info="{&quot;key&quot;:&quot;value-3&quot;}"
+    />
+</dataset>
\ No newline at end of file
diff --git a/dao/src/test/resources/dbunit/widgets_bundle.xml b/dao/src/test/resources/dbunit/widgets_bundle.xml
new file mode 100644
index 0000000..10a8d22
--- /dev/null
+++ b/dao/src/test/resources/dbunit/widgets_bundle.xml
@@ -0,0 +1,56 @@
+<dataset>
+    <widgets_bundle
+        id="uuid'250ac7b4-2825-11e7-93ae-92361f002671'"
+        tenant_id="uuid'250aca8e-2825-11e7-93ae-92361f002671'"
+        alias="WB1"
+        title="Widgets Bundle 1"
+        search_text="WB SEARCH TEXT 1"
+    />
+    <widgets_bundle
+        id="uuid'3269c18a-2825-11e7-93ae-92361f002671'"
+        tenant_id="uuid'3269c18a-2825-11e7-93ae-92361f002671'"
+        alias="WB2"
+        title="Widgets Bundle 2"
+        search_text="WB SEARCH TEXT 2"
+    />
+    <widgets_bundle
+        id="uuid'44e6af4e-2825-11e7-93ae-92361f002671'"
+        tenant_id="uuid'250aca8e-2825-11e7-93ae-92361f002671'"
+        alias="WB3"
+        title="Widgets Bundle 3"
+        search_text="WB SEARCH TEXT 3"
+    />
+    <widgets_bundle
+        id="uuid'696dc9b4-2830-11e7-93ae-92361f002671'"
+        alias="WB4"
+        title="Widgets Bundle 4"
+        search_text="SYSTEM BUNDLE 1"
+    />
+    <widgets_bundle
+        id="uuid'1a83fc50-2840-11e7-93ae-92361f002671'"
+        alias="WB5"
+        title="Widgets Bundle 5"
+        search_text="SYSTEM BUNDLE 2"
+    />
+    <widgets_bundle
+        id="uuid'6a593dde-2841-11e7-93ae-92361f002671'"
+        alias="WB6"
+        title="Widgets Bundle 6"
+        search_text="SYSTEM BUNDLE 1"
+    />
+    <widgets_bundle
+        id="uuid'3beb4b1a-294d-11e7-93ae-92361f002671'"
+        alias="WB6"
+        title="Widgets Bundle 7"
+        search_text="ABC DEF"
+    />
+    <!--
+    <widgets_bundle
+        id=""
+        tenant_id=""
+        alias=""
+        title=""
+        search_text=""
+    />
+    -->
+</dataset>
\ No newline at end of file
diff --git a/dao/src/test/resources/jpa-test.properties b/dao/src/test/resources/jpa-test.properties
new file mode 100644
index 0000000..7fff922
--- /dev/null
+++ b/dao/src/test/resources/jpa-test.properties
@@ -0,0 +1,7 @@
+cassandra.enabled=false
+
+sql.enabled=true
+sql.datasource.url=jdbc:h2:mem:thingsboard
+sql.datasource.username=sa
+sql.datasource.password=
+

pom.xml 19(+19 -0)

diff --git a/pom.xml b/pom.xml
index 64017d7..909936f 100755
--- a/pom.xml
+++ b/pom.xml
@@ -71,6 +71,9 @@
         <springfox-swagger.version>2.6.1</springfox-swagger.version>
         <bouncycastle.version>1.56</bouncycastle.version>
         <winsw.version>2.0.1</winsw.version>
+        <h2.version>1.4.194</h2.version>
+        <dbunit.version>2.5.3</dbunit.version>
+        <spring-test-dbunit.version>1.2.1</spring-test-dbunit.version>
     </properties>
 
     <modules>
@@ -443,6 +446,11 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
+                <groupId>com.github.springtestdbunit</groupId>
+                <artifactId>spring-test-dbunit</artifactId>
+                <version>${spring-test-dbunit.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>io.jsonwebtoken</groupId>
                 <artifactId>jjwt</artifactId>
                 <version>${jjwt.version}</version>
@@ -641,6 +649,12 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
+                <groupId>org.dbunit</groupId>
+                <artifactId>dbunit</artifactId>
+                <version>${dbunit.version}</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
                 <groupId>org.mockito</groupId>
                 <artifactId>mockito-all</artifactId>
                 <version>${mockito.version}</version>
@@ -713,6 +727,11 @@
                 <version>${bouncycastle.version}</version>
             </dependency>
             <dependency>
+                <groupId>com.h2database</groupId>
+                <artifactId>h2</artifactId>
+                <version>${h2.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>com.sun.winsw</groupId>
                 <artifactId>winsw</artifactId>
                 <version>${winsw.version}</version>