commit 2d9fab1088fc73e192d90cdc2ea7c865adf9099e
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Sat May 9 22:06:09 2015 +0200

    n-1 relation

diff --git a/example/main.cpp b/example/main.cpp
index d245dbc..e1d99ea 100644
--- a/example/main.cpp
+++ b/example/main.cpp
@@ -10,30 +10,41 @@
 #include "models/group.h"
 #include "../src/entity.h"
 #include "../src/entitymanager.h"
+#include "../src/relation.h"
 #include <QGenericReturnArgument>
+#include "entityinstancefactory.h"
 /**
   * create,remove und merge funktionieren
  */
-
+using namespace CuteEntityManager;
 int main(int argc, char *argv[]) {
-    Q_UNUSED(argc) Q_UNUSED(argv)
-    CuteEntityManager::EntityManager *e = new CuteEntityManager::EntityManager("QSQLITE",
-            QDir::currentPath() + "/db.sqlite");
-    QSharedPointer<Artikel> a = QSharedPointer<Artikel>(new Artikel(20.0, "Müsli"));
-    auto ep = a.dynamicCast<CuteEntityManager::Entity>();
-    qDebug() << e;
-    qDebug() << "Tabelle artikel erstellt:" << e->createTable(ep);
-    e->create(ep);
+//    Q_UNUSED(argc) Q_UNUSED(argv)
+//    CuteEntityManager::EntityManager *e = new CuteEntityManager::EntityManager("QSQLITE",
+//            QDir::currentPath() + "/db.sqlite");
+//    QSharedPointer<Artikel> a = QSharedPointer<Artikel>(new Artikel(20.0, "Müsli"));
+//    auto ep = a.dynamicCast<CuteEntityManager::Entity>();
+//    qDebug() << e;
+//    qDebug() << "Tabelle artikel erstellt:" << e->createTable(ep);
+//    e->create(ep);
 
-    QSharedPointer<CuteEntityManager::Entity> p = QSharedPointer<CuteEntityManager::Entity>(new Person("Max", "Mustermann", Person::MALE, "", "", "",
-                               QDate::currentDate()));
-    auto pptr = p.dynamicCast<CuteEntityManager::Entity>();
-    e->createTable(pptr);
-    e->create(pptr);
+//    QSharedPointer<CuteEntityManager::Entity> p = QSharedPointer<CuteEntityManager::Entity>(new Person("Max", "Mustermann", Person::MALE, "", "", "",
+//                               QDate::currentDate()));
+//    auto pptr = p.dynamicCast<CuteEntityManager::Entity>();
+//    e->createTable(pptr);
+//    e->create(pptr);
+//e->createTable(grp.dynamicCast<CuteEntityManager::Entity>());
 
     QSharedPointer<Group> grp = QSharedPointer<Group>(new Group());
-    e->createTable(grp.dynamicCast<CuteEntityManager::Entity>());
+
     grp.data()->setTeacher(new Person("Test", "Test12345"));
     grp.data()->setTeacherP(QSharedPointer<Person>(new Person("Max", "Mustermann")));
+    auto meta = grp.data()->getRelationProperties();
+    auto iterator = meta.constBegin();
+    while(iterator != meta.constEnd()) {
+        qDebug() << EntityInstanceFactory::extractEntityType(iterator.value().typeName());
+        //qDebug() << e.Type;
+        ++iterator;
+    }
+
     return 0;
 }
diff --git a/example/models/group.cpp b/example/models/group.cpp
index 6a7fc29..052c831 100644
--- a/example/models/group.cpp
+++ b/example/models/group.cpp
@@ -49,7 +49,7 @@ void Group::personChangedSlot() {
     qDebug() << "changed!";
 }
 
-QHash<QString, CuteEntityManager::Relation> Group::getRelations() {
+const QHash<QString, CuteEntityManager::Relation> Group::getRelations() const {
     QHash<QString, CuteEntityManager::Relation> h = QHash<QString, CuteEntityManager::Relation>();
     CuteEntityManager::Relation r = CuteEntityManager::Relation("artikel", CuteEntityManager::MANY_TO_ONE);
     h.insert("artikel", r);
diff --git a/example/models/group.h b/example/models/group.h
index c488d99..a780e11 100644
--- a/example/models/group.h
+++ b/example/models/group.h
@@ -36,7 +36,7 @@ Q_PROPERTY(QList<Person*> persons READ getPersons WRITE setPersons NOTIFY person
     void personChangedSlot();
 
   public:
-    virtual QHash<QString, CuteEntityManager::Relation> getRelations();
+    virtual const QHash<QString, CuteEntityManager::Relation> getRelations() const;
     // constructor
     Group();
 
diff --git a/src/entity.cpp b/src/entity.cpp
index cb6cc37..a792a1f 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -61,13 +61,13 @@ const QHash<QString, QMetaProperty> Entity::getMetaProperties() const {
     return h;
 }
 
-const QHash<QString, QMetaProperty> Entity::getRelationProperties() const {
-    auto h = QHash<QString, QMetaProperty>();
+const QHash<Relation, QMetaProperty> Entity::getRelationProperties() const {
+    auto h = QHash<Relation, QMetaProperty>();
     auto relations = this->getRelations();
     for (int var = 0; var < this->metaObject()->propertyCount(); ++var) {
         QMetaProperty m = this->metaObject()->property(var);
         if (m.isValid() && relations.contains(QString(m.name()))) {
-            h.insert(m.name(), m);
+            h.insert(relations.value(m.name()), m);
         }
     }
     return h;
diff --git a/src/entity.h b/src/entity.h
index a0fa073..d9665d3 100644
--- a/src/entity.h
+++ b/src/entity.h
@@ -53,7 +53,7 @@ class Entity : public QObject {
     //return value must be the exact name defined in Q_PROPERTY
     virtual QString getPrimaryKey();
     const QHash<QString, QMetaProperty> getMetaProperties() const;
-    const QHash<QString, QMetaProperty> getRelationProperties() const;
+    const QHash<Relation, QMetaProperty> getRelationProperties() const;
     const char *getClassname() const;
 
     qint64 getId() const;
diff --git a/src/entityinstancefactory.cpp b/src/entityinstancefactory.cpp
index 5ea64fc..3f41be1 100644
--- a/src/entityinstancefactory.cpp
+++ b/src/entityinstancefactory.cpp
@@ -64,3 +64,13 @@ Entity *EntityInstanceFactory::setAttributes(Entity *e, const QHash<QString, QVa
     auto metaprops = e->getMetaProperties();
     return EntityInstanceFactory::setAttributes(e, attributes, metaprops);
 }
+
+const QString EntityInstanceFactory::extractEntityType(const QString &s) {
+    QString r = "";
+    const QString sptr = "QSharedPointer";
+    if (s.contains(sptr)) {
+        const int index = s.indexOf(sptr) + sptr.count() +1;
+        r = s.mid(index,s.indexOf(">",index)-index);
+    }
+    return r;
+}
diff --git a/src/entityinstancefactory.h b/src/entityinstancefactory.h
index 128866a..dea64f0 100644
--- a/src/entityinstancefactory.h
+++ b/src/entityinstancefactory.h
@@ -30,6 +30,7 @@ class EntityInstanceFactory {
     static Entity *setAttributes(Entity *e, const QHash<QString, QVariant> &attributes,
                                  QHash<QString, QMetaProperty> metaprops);
     static Entity *setAttributes(Entity *e, const QHash<QString, QVariant> &attributes);
+    static const QString extractEntityType(const QString &s);
 
     template<typename T>
     static Entity *createInstance() {
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index a1888ed..feec3f5 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -116,6 +116,24 @@ void EntityManager::removeConnectionName(const QString &name) {
     EntityManager::connectionNames.removeOne(name);
 }
 
+QSharedPointer<Entity> EntityManager::findById(const qint64 &id, Entity *&e) {
+    QSharedPointer<Entity> r;
+    if (e) {
+        if ((r = this->cache.get(id, QString(e->getClassname()))) && !r.data()) {
+            auto map  = this->findByPk(id, e->getTablename());
+            r = this->convert(map, e->getClassname());
+        }
+        delete e;
+    }
+    return r;
+}
+
+QSharedPointer<Entity> EntityManager::findById(const qint64 &id, const QString &classname) {
+    Entity *e = EntityInstanceFactory::createInstance(classname);
+    return this->findById(id, e);
+
+}
+
 QSharedPointer<Entity> EntityManager::convert(const QHash<QString, QVariant> &map, const char *classname) {
     auto ptr = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(classname, map));
     this->cache.insert(ptr);
@@ -135,8 +153,11 @@ QList<QSharedPointer<Entity> > EntityManager::convert(QList<QHash<QString, QVari
 void EntityManager::manyToOne(const QSharedPointer<Entity> &entity, const QVariant &id, const QMetaProperty &property) {
     qint64 convertedId = -1;
     bool ok = false;
-    if((convertedId == id.toLongLong(&ok)) && ok && convertedId > -1) {
-        //property.t
+    if ((convertedId == id.toLongLong(&ok)) && ok && convertedId > -1) {
+        QSharedPointer<Entity> ptr = this->findById(convertedId, EntityInstanceFactory::extractEntityType(property.typeName()));
+        if (ptr.data() && ptr.data()->getId() > -1) {
+            property.write(entity.data(), QVariant(ptr));
+        }
     }
 }
 
@@ -204,7 +225,7 @@ QStringList EntityManager::getConnectionNames() {
     return EntityManager::connectionNames;
 }
 
-QHash<QString, QVariant> EntityManager::findById(qint64 id, QString tblname) {
+QHash<QString, QVariant> EntityManager::findByPk(qint64 id, QString tblname) {
     QSqlQuery q = this->schema.data()->getQueryBuilder().data()->find(id, tblname);
     this->db->select(q);
     QSqlRecord rec = q.record();
@@ -277,12 +298,11 @@ QList<QHash <QString, QVariant> > EntityManager::findAll(QString tblname) {
 }
 
 void EntityManager::resolveRelations(const QSharedPointer<Entity> &entity, const QHash<QString, QVariant> &map) {
-    auto relations = entity.data()->getRelations();
     auto props = entity.data()->getRelationProperties();
-    auto iterator = relations.constBegin();
-    while (iterator != relations.constEnd()) {
-        const Relation r = iterator.value();
-        const QMetaProperty property = props.value(r.getPropertyName());
+    auto iterator = props.constBegin();
+    while (iterator != props.constEnd()) {
+        const Relation r = iterator.key();
+        const QMetaProperty property = iterator.value();
         switch (r.getType()) {
         case MANY_TO_ONE:
             if (map.contains(r.getPropertyName()) + "_id") {
diff --git a/src/entitymanager.cpp.autosave b/src/entitymanager.cpp.autosave
deleted file mode 100644
index a1888ed..0000000
--- a/src/entitymanager.cpp.autosave
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Copyright (C) 2015 Christian Ehringfeld <c.ehringfeld@t-online.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "entitymanager.h"
-#include "enums/databasetype.h"
-#include "databasemigration.h"
-using namespace CuteEntityManager;
-
-QStringList EntityManager::connectionNames = QStringList();
-
-void EntityManager::init() {
-    auto schema = Database::getSchema(Database::getDatabaseType(
-                                          this->db.data()->getDatabase().driverName()), this->db);
-    this->schema = QSharedPointer<Schema>(schema);
-    this->schema.data()->setTables(this->schema.data()->getTableSchemas());
-}
-
-EntityManager::EntityManager(QSqlDatabase database) {
-    auto db = new Database(database);
-    this->db = QSharedPointer<Database>(db);
-    this->init();
-}
-
-bool EntityManager::startup(QString version, QStringList toInitialize) {
-    DatabaseMigration *dbm = new DatabaseMigration();
-    QSharedPointer<Entity> ptrDbm = QSharedPointer<Entity>(dbm);
-    QHash<QString, QVariant> map = QHash<QString, QVariant>();
-    bool ok = true;
-    map.insert("version", version);
-    if (this->findAllByAttributes(map, dbm->getTablename()).isEmpty()) {
-        for (int var = 0; var < toInitialize.size(); ++var) {
-            if (ok) {
-                QString c = toInitialize.at(var);
-                ok = this->createTable(QSharedPointer<Entity>(EntityInstanceFactory::createInstance(c)));
-            } else {
-                break;
-            }
-        }
-        if (ok) {
-            dbm->setVersion(version);
-            dbm->setApplyTime(QDateTime::currentDateTime());
-            this->create(ptrDbm);
-        }
-    }
-    delete dbm;
-    return ok;
-}
-
-EntityManager::EntityManager(const QString &databaseType, QString databasename , QString hostname, QString username,
-                             QString password, QString port) {
-    auto db = new Database(databaseType, this->createConnection(), hostname, databasename, username, password,
-                           port.toInt());
-    this->db = QSharedPointer<Database>(db);
-    this->init();
-}
-
-bool EntityManager::checkTable(const QSharedPointer<Entity> &entity) {
-    bool rc = true;
-    if (!this->schema.data()->containsTable(entity.data()->getTablename())) {
-        if (this->schema.data()->getQueryBuilder().data()->createTable(entity)) {
-            this->schema.data()->getTableSchema(entity.data()->getTablename(), true);
-            rc = this->schema.data()->getTables().contains(entity.data()->getTablename());
-        }
-    }
-    return rc;
-}
-
-QSharedPointer<Database> EntityManager::getDb() const {
-    return db;
-}
-
-void EntityManager::setDb(const QSharedPointer<Database> &value) {
-    db = value;
-}
-
-QSharedPointer<Schema> EntityManager::getSchema() const {
-    return schema;
-}
-
-void EntityManager::setSchema(const QSharedPointer<Schema> &value) {
-    schema = value;
-}
-
-QString EntityManager::createConnection() {
-    QStringList l = EntityManager::getConnectionNames();
-    QString conName = "";
-    bool ok = false;
-    qint16 i = 0;
-    while (!ok) {
-        if (l.contains("con" + QString::number(i))) {
-            ++i;
-        } else {
-            l.append("con" + QString::number(i));
-            ok = true;
-            conName = "con" + QString::number(i);
-            EntityManager::setConnectionNames(l);
-        }
-    }
-    return conName;
-}
-
-void EntityManager::removeConnectionName(const QString &name) {
-    EntityManager::connectionNames.removeOne(name);
-}
-
-QSharedPointer<Entity> EntityManager::convert(const QHash<QString, QVariant> &map, const char *classname) {
-    auto ptr = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(classname, map));
-    this->cache.insert(ptr);
-    return ptr;
-}
-
-QList<QSharedPointer<Entity> > EntityManager::convert(QList<QHash<QString, QVariant> > maps, const char *classname) {
-    auto list = QList<QSharedPointer<Entity> >();
-    for (int var = 0; var < maps.size(); ++var) {
-        auto ptr = this->convert(maps.at(var), classname);
-        list.append(ptr);
-        this->cache.insert(ptr);
-    }
-    return list;
-}
-
-void EntityManager::manyToOne(const QSharedPointer<Entity> &entity, const QVariant &id, const QMetaProperty &property) {
-    qint64 convertedId = -1;
-    bool ok = false;
-    if((convertedId == id.toLongLong(&ok)) && ok && convertedId > -1) {
-        //property.t
-    }
-}
-
-void EntityManager::oneToMany(const QSharedPointer<Entity> &entity, const Relation &r, const QMetaProperty &property) {
-
-}
-
-void EntityManager::manyToMany(const QSharedPointer<Entity> &entity, const Relation &r, const QMetaProperty &property) {
-
-}
-
-void EntityManager::oneToOne(const QSharedPointer<Entity> &entity, const Relation &r, const QMetaProperty &property,
-                             const QVariant &id) {
-
-}
-
-QList<QSharedPointer<Entity> > EntityManager::findEntityByAttributes(const QSharedPointer<Entity> &entity,
-        bool ignoreID) {
-    auto maps = this->findAllByAttributes(entity, ignoreID);
-    return this->convert(maps, entity.data()->getClassname());
-}
-
-/**
- * @todo should be an insert statement with much values
- * not really usefull atm
- * @brief EntityManager::create
- * @param entities
- * @return
- */
-bool EntityManager::create(QList<QSharedPointer<Entity> > entities) {
-    bool ok = true;
-    foreach (QSharedPointer<Entity> ent, entities) {
-        ok = this->create(ent);
-        if (!ok) {
-            break;
-        }
-    }
-    return ok;
-}
-
-/**
- * @TODO insert Relations
- * @brief EntityManager::create
- * @param entity
- * @return
- */
-bool EntityManager::create(QSharedPointer<Entity> &entity) {
-    bool rc = false;
-    if (this->checkTable(entity) && this->count(entity) == 0) {
-        QSqlQuery q = this->schema.data()->getQueryBuilder().data()->create(entity);
-        rc = this->db->transaction(q);
-        if (rc) {
-            entity.data()->setId(this->schema.data()->getLastInsertID().toLongLong(&rc));
-            this->cache.insert(entity);
-        }
-    }
-    return rc;
-}
-
-EntityManager::~EntityManager() {
-    EntityManager::removeConnectionName(this->db->getConnectionName());
-}
-
-QStringList EntityManager::getConnectionNames() {
-    return EntityManager::connectionNames;
-}
-
-QHash<QString, QVariant> EntityManager::findById(qint64 id, QString tblname) {
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->find(id, tblname);
-    this->db->select(q);
-    QSqlRecord rec = q.record();
-    QHash<QString, QVariant> map = QHash<QString, QVariant>();
-    if (q.next()) {
-        for (int var = 0; var < rec.count(); ++var) {
-            QVariant variant = rec.value(var);
-            if (variant.isValid()) {
-                map.insert(rec.fieldName(var), variant);
-            }
-        }
-    }
-    return map;
-}
-
-
-QList<QHash<QString, QVariant> > EntityManager::findAllByAttributes(const QSharedPointer<Entity> &entity,
-        bool ignoreID) {
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->findByAttributes(entity, ignoreID);
-    return this->convertQueryResult(q);
-}
-
-QList<QHash <QString, QVariant> > EntityManager::findAllByAttributes(const QHash<QString, QVariant> &m,
-        const QString &tblname,
-        bool ignoreID) {
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->findByAttributes(m,
-                  tblname, ignoreID);
-    return this->convertQueryResult(q);
-}
-
-/**
- * @TODO insert Relations
- * @brief EntityManager::merge
- * @param entity
- * @param withRelations
- * @return
- */
-bool EntityManager::merge(QSharedPointer<Entity> &entity, bool withRelations) {
-    if (this->count(entity) == 0 && entity->getId() != -1) {
-        QSqlQuery q = this->schema.data()->getQueryBuilder().data()->merge(entity);
-        return this->db->transaction(q);
-    } else {
-        return false;
-    }
-}
-
-
-QList<QHash<QString, QVariant> > EntityManager::convertQueryResult(QSqlQuery &q) {
-    QList<QHash <QString, QVariant> > listmap = QList<QHash <QString, QVariant> >();
-    this->db->select(q);
-    QSqlRecord rec = q.record();
-    QStringList l = QStringList();
-    qint16 field_count = rec.count();
-    for (int var = 0; var < field_count; ++var) {
-        l.append(rec.fieldName(var));
-    }
-    QHash<QString, QVariant> map = QHash<QString, QVariant>();
-    while (q.next()) {
-        for (int var = 0; var < field_count; ++var) {
-            map.insert(l.at(var), q.value(rec.indexOf(l.at(var))));
-        }
-        listmap.append(map);
-    }
-    return listmap;
-}
-
-QList<QHash <QString, QVariant> > EntityManager::findAll(QString tblname) {
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->findAll(tblname);
-    return this->convertQueryResult(q);
-}
-
-void EntityManager::resolveRelations(const QSharedPointer<Entity> &entity, const QHash<QString, QVariant> &map) {
-    auto relations = entity.data()->getRelations();
-    auto props = entity.data()->getRelationProperties();
-    auto iterator = relations.constBegin();
-    while (iterator != relations.constEnd()) {
-        const Relation r = iterator.value();
-        const QMetaProperty property = props.value(r.getPropertyName());
-        switch (r.getType()) {
-        case MANY_TO_ONE:
-            if (map.contains(r.getPropertyName()) + "_id") {
-                this->manyToOne(entity, property.read(entity.data()), property);
-            }
-            break;
-        case MANY_TO_MANY:
-            this->manyToMany(entity, r, property);
-            break;
-        case ONE_TO_MANY:
-            this->oneToMany(entity, r, property);
-            break;
-        case ONE_TO_ONE:
-            this->oneToOne(entity, r, property, property.read(entity.data()));
-            break;
-        }
-        ++iterator;
-    }
-}
-
-bool EntityManager::save(QSharedPointer<Entity> &entity) {
-    if (entity.data()->getId() > -1) {
-        return this->merge(entity);
-    } else {
-        return this->create(entity);
-    }
-}
-
-qint64 EntityManager::findId(QSharedPointer<Entity> &entity) {
-    qint64 r = -1;
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->findId(entity);
-    this->db->select(q);
-    if (q.next()) {
-        r = q.value(0).toLongLong();
-    }
-    return r;
-}
-
-
-bool EntityManager::remove(QSharedPointer<Entity> &entity) {
-    bool rc = false;
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->remove(entity);
-    if (this->db->transaction(q)) {
-        this->cache.remove(entity);
-        entity.clear();
-        rc = true;
-    }
-    return rc;
-}
-
-bool EntityManager::createTable(const QSharedPointer<Entity> &entity) {
-    return this->schema.data()->getQueryBuilder().data()->createTable(entity);
-}
-
-qint8 EntityManager::count(const QSharedPointer<Entity> &entity, bool ignoreID) {
-    qint8 rc = -1;
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->count(entity, ignoreID);
-    this->db->select(q);
-    if (q.next()) {
-        rc = q.value(0).toInt();
-    }
-    return rc;
-}
-
-qint8 EntityManager::count(const QString &tableName) {
-    qint8 rc = -1;
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->count(tableName);
-    this->db->select(q);
-    if (q.next()) {
-        rc = q.value(0).toInt();
-    }
-    return rc;
-}
-
-void EntityManager::setConnectionNames(QStringList list) {
-    EntityManager::connectionNames = list;
-}
diff --git a/src/entitymanager.h b/src/entitymanager.h
index 5b60b4e..e3b155a 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -52,7 +52,7 @@ class EntityManager {
     void init();
     QList<QHash<QString, QVariant> > findAll(QString tblname);
     void resolveRelations(const QSharedPointer<Entity> &entity, const QHash<QString, QVariant> &map);
-    QHash<QString, QVariant> findById(qint64 id, QString tblname);
+    QHash<QString, QVariant> findByPk(qint64 id, QString tblname);
     QSharedPointer<Entity> convert(const QHash<QString, QVariant> &map, const char *classname);
     QList<QSharedPointer<Entity>> convert(QList<QHash<QString, QVariant> > maps, const char *classname);
     void manyToOne(const QSharedPointer<Entity> &entity, const QVariant &id, const QMetaProperty &property);
@@ -63,6 +63,7 @@ class EntityManager {
     QList<QHash<QString, QVariant> > findAllByAttributes(const QSharedPointer<Entity> &entity, bool ignoreID = false);
     QList<QHash<QString, QVariant> > findAllByAttributes(const QHash<QString, QVariant> &m, const QString &tblname,
             bool ignoreID = false);
+    QSharedPointer<Entity> findById(const qint64 &id, Entity *&e);
 
   public:
     EntityManager(QSqlDatabase database);
@@ -78,6 +79,7 @@ class EntityManager {
      */
     bool startup(QString version, QStringList toInitialize);
     static void removeConnectionName(const QString &name);
+    QSharedPointer<Entity> findById(const qint64 &id, const QString &classname);
     QList<QSharedPointer<Entity>> findEntityByAttributes(const QSharedPointer<Entity> &entity, bool ignoreID = false);
     bool create(QList<QSharedPointer<Entity>> entities);
     bool create(QSharedPointer<Entity> &entity);
@@ -118,30 +120,9 @@ class EntityManager {
         return QList<QSharedPointer<Entity>>();
     }
 
-    template<class T>  QSharedPointer<Entity> findById(qint64 id) {
-        Entity *e = EntityInstanceFactory::createInstance<T>();
-        QSharedPointer<Entity> r;
-        if (e) {
-            if ((r = this->cache.get(id, QString(e->getClassname()))) && !r.data()) {
-                auto map  = this->findById(id, e->getTablename());
-                r = this->convert(map, e->getClassname());
-            }
-            delete e;
-        }
-        return r;
-    }
-
     template<class T> QSharedPointer<Entity> findById(const qint64 &id) {
         Entity *e = EntityInstanceFactory::createInstance<T>();
-        QSharedPointer<Entity> r;
-        if (e) {
-            if ((r = this->cache.get(id, QString(e->getClassname()))) && !r.data()) {
-                auto map = this->findById(id, e->getTablename());
-                r = this->convert(map, e->getClassname());
-            }
-            delete e;
-        }
-        return r;
+        return this->findById(id, e);
     }
 
     template<class T> QSharedPointer<Entity> findEntityByAttributes(const QHash<QString, QString> &attributes) {
diff --git a/src/relation.h b/src/relation.h
index 6fc20a6..b7b1ccf 100644
--- a/src/relation.h
+++ b/src/relation.h
@@ -16,6 +16,7 @@
 #ifndef RELATION_H
 #define RELATION_H
 #include <QString>
+#include <QHash>
 namespace CuteEntityManager {
 enum RelationType {
     ONE_TO_ONE, //e.g. specialization, heritage
@@ -72,6 +73,15 @@ class Relation {
     bool optional;
 
 };
+
+inline bool operator==(const Relation &e1, const Relation &e2) {
+    return e1.getPropertyName() == e2.getPropertyName();
+}
+
+inline uint qHash(const Relation &key, uint seed) {
+    return qHash(key.getPropertyName(), seed);
+}
+
 }
 
 #endif // RELATION_H
