commit 554f7bc0fd2eac31e6949ff54ad37b22fd286d7f
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Sun Aug 9 23:08:07 2015 +0200

    has changed method

diff --git a/samples/example/main.cpp b/samples/example/main.cpp
index 0992e0a..76868a5 100644
--- a/samples/example/main.cpp
+++ b/samples/example/main.cpp
@@ -82,6 +82,7 @@ int main(int argc, char *argv[]) {
     qWarning() << "-----------------------------";
 
     QSharedPointer<Entity> personFindPtr = e->findById(1, QString("Person"));
+    qDebug() << "HASCHANGED:" << e->hasChanged(personFindPtr);
     e->refresh(personFindPtr);
     QSharedPointer<Person> pers = personFindPtr.objectCast<Person>();
     qWarning() << "MainTeacher:" << personFindPtr->toString();
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index b8194c7..8ef2b93 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -179,6 +179,47 @@ bool EntityManager::validate(QSharedPointer<Entity> &entity) {
     return !entity->hasErrors();
 }
 
+bool EntityManager::hasChanged(QSharedPointer<Entity> &entity) {
+    bool changed = true;
+    if (entity->getId() >= -1) {
+        changed = false;
+        auto listmap = this->findByPk(entity->getId(), entity);
+        auto relations = entity->getRelations();
+        QStringList rels = QStringList();
+        for (auto i = relations.constBegin(); i != relations.constEnd(); ++i) {
+            if (i.value().getType() == RelationType::MANY_TO_ONE
+                    || (i.value().getType() == RelationType::ONE_TO_ONE
+                        && i.value().getMappedBy().isEmpty())) {
+                rels.append(this->schema->getQueryBuilder()->generateColumnNameID(i.key()));
+            }
+        }
+        for (auto i = listmap.constBegin(); i != listmap.constEnd(); ++i) {
+            if (rels.contains(i.key())) {
+                QString appendix =
+                    this->schema->getQueryBuilder()->columnNameIDAppendix();
+                QString relKey = i.key();
+                QVariant v = entity->getProperty(relKey.remove(relKey.size() - appendix.size(),
+                                                 appendix.size()));
+                if (!v.isNull()) {
+                    auto entity = EntityInstanceFactory::castQVariant(v);
+                    if (entity->getProperty(entity->getPrimaryKey()) != i.value()) {
+                        changed = true;
+                        break;
+                    }
+                }
+            } else {
+                QVariant property = entity->getProperty(i.key());
+                changed = i.value() != property && !(i.value().isNull() && property.isNull());
+                if (changed) {
+                    break;
+                }
+            }
+        }
+
+    }
+    return changed;
+}
+
 QString EntityManager::createConnection() {
     QStringList l = EntityManager::getConnectionNames();
     QString conName = "";
diff --git a/src/entitymanager.h b/src/entitymanager.h
index 0b7819e..07c19cf 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -78,6 +78,8 @@ class EntityManager : public QObject {
     QList<QHash<QString, QVariant> > selectBySql(const QString &sql);
     qint8 count(Query &query);
     bool validate(QSharedPointer<Entity> &entity);
+    bool hasChanged(QSharedPointer<Entity> &entity);
+
 
   public:
     EntityManager(QSqlDatabase database, bool logQueries = false);
diff --git a/src/querybuilder.cpp b/src/querybuilder.cpp
index 4993728..5bddb65 100644
--- a/src/querybuilder.cpp
+++ b/src/querybuilder.cpp
@@ -287,7 +287,11 @@ QString QueryBuilder::generateIndexName(const QString &name,
 }
 
 QString QueryBuilder::generateColumnNameID(QString name) const {
-    return name.append("_id");
+    return name.append(this->columnNameIDAppendix());
+}
+
+QString QueryBuilder::columnNameIDAppendix() const {
+    return "_id";
 }
 
 QString QueryBuilder::getForeignKeyCascade(DbForeignKeyCascade cascade) const {
diff --git a/src/querybuilder.h b/src/querybuilder.h
index bd4c135..3850afb 100644
--- a/src/querybuilder.h
+++ b/src/querybuilder.h
@@ -234,6 +234,7 @@ class QueryBuilder {
     QString generateIndexName(const QString &name, const QString &table,
                               const QString &refColumn, const QString &refTable, const bool fk) const;
     QString generateColumnNameID(QString name) const;
+    QString columnNameIDAppendix() const;
     virtual void createRelationFK(QStringList &queries,
                                   const QSharedPointer<Entity> &entity, const Relation &relation,
                                   const QMetaProperty &metaProperty, const QString &update,
