diff --git a/app/builders/learning_object_builder.rb b/app/builders/learning_object_builder.rb
index d7e5cf5701e3f2208b3e6cf5850ce8323782e9cb..cacd73f179d6cb7e865cd629d3d6241849fde944 100644
--- a/app/builders/learning_object_builder.rb
+++ b/app/builders/learning_object_builder.rb
@@ -23,18 +23,21 @@ class LearningObjectBuilder
     unless args.nil?
       # cache object when build
       lo = Rails.cache.fetch(cache_key(args['@rid'], args['last_modified']), expires_in: 12.hours) do
-        LearningObject.new(
+        obj = LearningObject.new(
           id: args['@rid'],
           name: args['name'],
           description: args['description'],
           thumbnail: args['thumbnail'],
-          created_at: args['created_at'],
           id_dspace: args['id_dspace'],
           type: args['type'],
           bitstreams: args['bitstreams'],
           last_modified: args['last_modified'],
           metadata: JSON.parse(args['metadata'])
         )
+        obj.created_at = DateTime.strptime(args['created_at'], "%Y-%m-%d %H:%M:%S") unless args['created_at'].nil?
+        obj.last_modified = DateTime.strptime(args['last_modified'], "%Y-%m-%d %H:%M:%S") unless args['last_modified'].nil?
+        obj.published_at = DateTime.strptime(args['published_at'], "%Y-%m-%d %H:%M:%S") unless args['published_at'].nil?
+        obj
       end
       lo.likes = args.key?('in_Likes') ? args['in_Likes'].size : 0
       lo.views = args.key?('in_Views') ? args['in_Views'].size : 0
diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb
index ade9205a8a48d81b0663b0d150320e36df8eb372..5f9b4f8cbcb543a434d3af3cd4bb347322f280f4 100644
--- a/app/models/learning_object.rb
+++ b/app/models/learning_object.rb
@@ -4,7 +4,7 @@ class LearningObject
 
   attr_accessor :id, :id_dspace, :rid, :name, :author, :description,
                 :published_at, :thumbnail, :created_at, :last_modified,
-                :type, :bitstreams, :metadata, :likes, :views,
+                :type, :grade_level, :bitstreams, :metadata, :likes, :views,
                 :downloads, :subjects, :attributes
 
   validates_presence_of :name, :created_at, :type, :likes, :views, :downloads
@@ -47,6 +47,7 @@ class LearningObject
   def get_metadata_values_of key
     values = []
     @metadata.each do |m|
+      m = m.with_indifferent_access
       values << m["value"] if m["key"] == key
     end
     values
@@ -81,8 +82,9 @@ class LearningObject
     {
         likes: 0,
         views: 0,
-        downloads: 0,
-        created_at: DateTime.now.strftime("%Y-%m-%d %H:%M:%S")
+        downloads: 0
+        # Setting this default value wont allow created_at to be set trough the constructor
+        # created_at: DateTime.new
     }
   end
 
diff --git a/app/repositories/orient_db/attribute_repository.rb b/app/repositories/orient_db/attribute_repository.rb
index 4c5373180e4f1aac39f80384dd3c8f78288ff5ba..683d7eb2ca63e97effafdd051d206da54df9af10 100644
--- a/app/repositories/orient_db/attribute_repository.rb
+++ b/app/repositories/orient_db/attribute_repository.rb
@@ -2,22 +2,24 @@ module OrientDb
   class AttributeRepository < Base
     
     def find_by_key_and_value(key, value)
-        result = connection.query sprintf("SELECT FROM %s WHERE key = '%s' AND value = '%s'", odb_class, key, value)
-        build_objects(result)
+      # Escape double quotes for OrientDB
+      v = value.gsub('"','\\"')
+      result = connection.query("SELECT EXPAND(rid) FROM INDEX:attr_unique WHERE key = [\"#{key}\", \"#{v}\"]")
+      build_object(result.first)
     end
 
     def build_object(args={})
-      subject = nil
+      attribute = nil
       unless args.nil?
-        subject = Attribute.new(:id => args["@rid"])
+        attribute = Attribute.new(:id => args["@rid"])
         args.each do |var, val|
           var_name = "@"+var
-          if subject.respond_to?(var)
-            subject.instance_variable_set(var_name, val)
+          if attribute.respond_to?(var)
+            attribute.instance_variable_set(var_name, val)
           end
         end
       end
-      subject
+      attribute
     end
     
     private
diff --git a/app/repositories/orient_db/base.rb b/app/repositories/orient_db/base.rb
index 2058b678bf332956363e7622eb9a92a94ecd5574..8ccf9939697b27eb58be82e3073654af83962b50 100644
--- a/app/repositories/orient_db/base.rb
+++ b/app/repositories/orient_db/base.rb
@@ -45,6 +45,8 @@ class OrientDb::Base
     objects
   end
 
+  # Take the object and make a hash in the OrientDB format. 
+  # Used to create a document.
   def build_hash(object)
     hash = {'@class' => odb_class}
     object.instance_variables.each do |var|
@@ -52,6 +54,9 @@ class OrientDb::Base
       hash[var_name] = sanitize_orientdb_values(object.instance_variable_get(var))
     end
     hash.delete('id')
+    # TODO: find a better way to ignore variables from ActiveModel
+    hash.delete("validation_context")
+    hash.delete("errors")
     hash
   end
 
@@ -60,6 +65,9 @@ class OrientDb::Base
   end
 
   def sanitize_orientdb_values(val)
+    if val.respond_to? "strftime"
+      val = val.strftime("%Y-%m-%d %H:%M:%S")
+    end
     val
   end
 
diff --git a/app/repositories/orient_db/learning_object_repository.rb b/app/repositories/orient_db/learning_object_repository.rb
index fb5a41a85708a575ee71a84a67ffcb35ed4ecd3a..77a56e3d1be7150deffd5e156cd6ac5df2b16dfb 100644
--- a/app/repositories/orient_db/learning_object_repository.rb
+++ b/app/repositories/orient_db/learning_object_repository.rb
@@ -186,6 +186,8 @@ module OrientDb
       hash.delete("downloads")
       hash.delete("subjects")
       hash.delete("attributes")
+
+      hash["metadata"] = hash["metadata"].to_json
       hash
     end
 
diff --git a/lib/orient_db/migration.rb b/lib/orient_db/migration.rb
index 69e52878fe072833848968c0cf12cec5c867773a..87a08d22e36aef6a0b9781df83d10f966fb644de 100644
--- a/lib/orient_db/migration.rb
+++ b/lib/orient_db/migration.rb
@@ -38,8 +38,8 @@ module OrientDb
     def add_index(klass, properties, type, name=nil, engine=nil, metadata=nil)
       engine = engine.nil? ? "" : " ENGINE #{engine}"
       metadata = metadata.nil? ? "" : " METADATA #{metadata.to_s}"
-      props = stringify(properties, ", ")
-      name = name.nil? ? "#{klass}."+stringify(properties, "_") : name;
+      props = properties.join(',')
+      name = name.nil? ? "#{klass}."+properties.join("_") : name;
 
       begin
         index = "CREATE INDEX #{name} ON #{klass} (#{props}) #{type}#{engine}#{metadata}"
@@ -53,16 +53,6 @@ module OrientDb
         end
       end
     end
-
-    private
-
-    def stringify(array, separator)
-      str = ""
-      array.each do |value|
-        str += value.to_s+separator
-      end
-      str[0..-(separator.size+1)]
-    end
-
+    
   end
 end
\ No newline at end of file
diff --git a/lib/orient_db/migrations.rb b/lib/orient_db/migrations.rb
index 838d6ae9dc1b7378e335eb994cc4de9091e97b1d..8155274e3a5a20843cc777c55950e8a24edad636 100644
--- a/lib/orient_db/migrations.rb
+++ b/lib/orient_db/migrations.rb
@@ -13,7 +13,7 @@ class OrientDb::Migrations
     # Vertices inheriting from Object
     @migrations << CreateInstitution.new(client)
     @migrations << CreateLearningObject.new(client)
-    # Vertices inheriting from LearningObject
+    # Vertices dependent on LearningObject
     @migrations << CreateCollection.new(client)
     @migrations << CreateSubject.new(client)
     @migrations << CreateMainPage.new(client)
@@ -27,6 +27,7 @@ class OrientDb::Migrations
     @migrations << CreateComments.new(client)
     @migrations << CreateCommentedBy.new(client)
     @migrations << CreateComplaint.new(client)
+    @migrations << CreateSubtopic.new(client)
   end
 
   ##
diff --git a/lib/orient_db/migrations/create_attribute.rb b/lib/orient_db/migrations/create_attribute.rb
index b297b6849e947efc44d1899e53f4164284f83fe3..634c1087ec16f68df17189e3515747d590af8969 100644
--- a/lib/orient_db/migrations/create_attribute.rb
+++ b/lib/orient_db/migrations/create_attribute.rb
@@ -5,7 +5,7 @@ class OrientDb::Migrations::CreateAttribute < OrientDb::Migration
         c.property 'key', :string
         c.property 'value', :string
     end
-    add_index 'Attribute', ['key'], "NOTUNIQUE_HASH_INDEX"
+    add_index 'Attribute', ['key','value'], "UNIQUE_HASH_INDEX", "attr_unique"
     metadata = {:analyzer => "org.apache.lucene.analysis.br.BrazilianAnalyzer"}
     add_index 'Attribute', ['value'], "FULLTEXT", nil, "LUCENE", metadata.to_json
   end
diff --git a/lib/orient_db/migrations/create_collection.rb b/lib/orient_db/migrations/create_collection.rb
index 20347685cc69cf00f0fa1ddecb18982f62b1e715..e421abef16ff42263b597ac01404a3fc66e288ea 100644
--- a/lib/orient_db/migrations/create_collection.rb
+++ b/lib/orient_db/migrations/create_collection.rb
@@ -3,6 +3,7 @@ class OrientDb::Migrations::CreateCollection < OrientDb::Migration
   def up
     create_class 'Collection', 'Object' do |c|
         c.property 'privacy', :string
+        c.property 'description', :string
         c.link     'learning_objects',  :linkset, 'LearningObject'
     end
   end
diff --git a/lib/orient_db/migrations/create_comment.rb b/lib/orient_db/migrations/create_comment.rb
index 7d5c2523a41aa3df69c09ca214a6dc39c9e4301a..8359681577de1b7b8f046ce19f65599b2371683f 100644
--- a/lib/orient_db/migrations/create_comment.rb
+++ b/lib/orient_db/migrations/create_comment.rb
@@ -1,8 +1,9 @@
 class OrientDb::Migrations::CreateComment < OrientDb::Migration
 
   def up
-    create_class 'Comment', 'Object' do |c|
+    create_class 'Comment', 'V' do |c|
       c.property 'text', :string
+      c.property 'created_at', :datetime
     end
   end
 
diff --git a/lib/orient_db/migrations/create_learning_object.rb b/lib/orient_db/migrations/create_learning_object.rb
index 7d3a15a66f66ad31de9cd7fcf201904e3a61848b..0b85030937b99b6c566377c2615d5a23f00990c5 100644
--- a/lib/orient_db/migrations/create_learning_object.rb
+++ b/lib/orient_db/migrations/create_learning_object.rb
@@ -6,6 +6,9 @@ class OrientDb::Migrations::CreateLearningObject < OrientDb::Migration
         c.property 'description', :string
         c.property 'thumbnail', :string
         c.property 'type', :string
+        c.property 'author', :string
+        c.property 'grade_level', :string
+        c.property 'published_at', :datetime
         c.property 'metadata', :string
     end
     add_index 'LearningObject', ['id_dspace'], "UNIQUE_HASH_INDEX"
diff --git a/lib/orient_db/migrations/create_subject.rb b/lib/orient_db/migrations/create_subject.rb
index cee8e81723ca32d8f52dbb6365136d0d90b7d486..140a7794c2da0a99a11e9b75c63214fb5cef9346 100644
--- a/lib/orient_db/migrations/create_subject.rb
+++ b/lib/orient_db/migrations/create_subject.rb
@@ -4,6 +4,7 @@ class OrientDb::Migrations::CreateSubject < OrientDb::Migration
     create_class 'Subject', 'Object' do |c|
         c.link 'highlights',  :linkset, 'LearningObject'
     end
+    add_index 'Subject', ['name'], "UNIQUE_HASH_INDEX"
   end
 
   def down
diff --git a/lib/orient_db/migrations/create_subtopic.rb b/lib/orient_db/migrations/create_subtopic.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1b43a0f46886f431067430ef423fd2aaa3217b94
--- /dev/null
+++ b/lib/orient_db/migrations/create_subtopic.rb
@@ -0,0 +1,10 @@
+class OrientDb::Migrations::CreateSubtopic < OrientDb::Migration
+
+  def up
+    create_class 'Subtopic', 'E'
+  end
+
+  def down
+    drop_class 'Subtopic'
+  end
+end
\ No newline at end of file
diff --git a/lib/tasks/dspace.rake b/lib/tasks/dspace.rake
index 6c424c386c3b2300947805fbb0c6f1e303c80f3b..68b4c1170048d162f922f9a969b1044d015e960b 100644
--- a/lib/tasks/dspace.rake
+++ b/lib/tasks/dspace.rake
@@ -41,10 +41,9 @@ namespace :dspace do
           result = learning_object_repository.get_by_dspace_id item.id
           if result.nil?
             learning_object = initialize_learning_object item
-            learning_object_repository.save learning_object
+            learning_object_repository.create learning_object
           end
         end
-
       end
 
     end
@@ -67,21 +66,23 @@ namespace :dspace do
   def initialize_learning_object item
     metadata = build_array_of(item.metadata)
     bitstreams = build_array_of(item.bit_streams)
-    current_date = Time.new
+    current_date = Time.now
 
-    LearningObject.new(
+    lo = LearningObject.new(
       :name => item.name,
-      :author => select_value_of(metadata, "dc.contributor.author"),
-      :description => select_value_of(metadata, "dc.description"),
-      :published_at => select_value_of(metadata, "dc.date.issued"),
-      :created_at => current_date,
       :last_modified => current_date,
+      :created_at => current_date,
       :id_dspace => item.id,
       :type => item.type,
       :thumbnail => nil,
       :bitstreams => bitstreams,
       :metadata => metadata
     )
+    lo.author = lo.get_metadata_values_of("dc.contributor.author").join(', ')
+    lo.description = lo.get_metadata_value_of("dc.description")
+    date = lo.get_metadata_value_of("dc.date.issued")
+    lo.published_at = Time.iso8601(date) unless date.nil?
+    lo
   end
 
   def build_array_of(item_content=[])
@@ -93,11 +94,4 @@ namespace :dspace do
     return content_array
   end
 
-  def select_value_of(array, key)
-    descriptions = array.select { |a|  a[:key] == key }
-    unless descriptions.empty?
-      descriptions.first[:value]
-    end
-  end
-
 end
diff --git a/lib/tasks/orientdb.rake b/lib/tasks/orientdb.rake
index 1cce055bcffeaa46aef05696976e1164fb08fdf8..77ad1eadf3e4d644af293a54af8dbd0a934b1454 100644
--- a/lib/tasks/orientdb.rake
+++ b/lib/tasks/orientdb.rake
@@ -26,12 +26,14 @@ namespace :orientdb do
     offset = 0
 
     loop do
-      puts " --> importing LearningObjects from #{offset} to #{offset+limit}"
+      puts " --> creating LearningObjects realations from #{offset} to #{offset+limit}"
 
       begin
         # Get LearningObjects from OrientDB (from offset to offset+limit)
         learning_objects = learning_object_repository.all_from_offset_to_limit(offset,limit)
-      rescue
+      rescue => e
+        puts e
+        puts e.backtrace
         # Sleeps for a while to wait database's recovery
         sleep(30.seconds)
         # Goes to next iteration to retry
@@ -41,31 +43,61 @@ namespace :orientdb do
         break if learning_objects.empty?
 
         learning_objects.each do |lo|
+          puts "LO ID ==== "+lo.id.to_s
+          # Get metadata as a hash with metadata name as key
           metadata = get_unique_matadata_keys(lo)
+          # Get subjects
           subjects = metadata["dc.subject.category"]
+          # If subjects is nil, set as empty array
           subjects ||= []
+          # Remove subjects from the metadata hash, so they wont be inserted as Attributes
           metadata.delete("dc.subject.category")
-
-          subjects_array=[]
-          attributes_array=[]
-
-          subjects.each do |subject_name|
-            subjects_array << {:name => subject_name}
+          # Set LearningObject relations attributes so it wont perform a search in the database when accessed
+          lo.subjects=[]
+          lo.attributes=[]
+          # Remove nil values from subjects array
+          subjects.compact!
+          subjects.each do |name|
+            # Look for subject with the same name
+            subject = subject_repository.find_by_name(name)
+            if subject.nil?
+              # Create a Subject with this name if it doesnt exist
+              subject = Subject.new(:name => name)
+              subject_repository.create(subject)
+            end
+            # Add subject on the LearningObject list
+            lo.subjects << subject
           end
 
-          metadata.each do |key, value|
-            attributes_array << {:key => key, :value => value}
+          metadata.each do |key, values|
+            # Remove nil values from values array
+            values.compact!
+            values.each do |v|
+              # Remove characters that might throw exceptions in OrientDB
+              v = v.delete('\\').delete('[').delete(']')
+              # Look for attribute with the same key and value
+              attribute = attribute_repository.find_by_key_and_value(key,v)
+              if attribute.nil?
+                # Create an Attribute with this key and value if it doesnt exist
+                attribute = Attribute.new(:key => key, :value => v)
+                attribute_repository.create(attribute)
+              end
+              # Add attribute on the LearningObject list
+              lo.attributes << attribute
+            end
           end
-
-          CreateRelationsWorker.perform_async(lo.id, subjects_array, attributes_array)
+          
+          # Create LearningObject relations that were added to its attrs
+          learning_object_repository.create_relations(lo)
         end
-
+        # Increase offset for next loop
         offset += limit
       end
     end
 
   end
 
+  # For each unique key on LearningObject metadata, get all its values and add on a new hash
   def get_unique_matadata_keys(lo)
     hash = {}
     lo.metadata.each do |m|