/**
 * Copyright (c) 2015-present Jorge Díaz All rights reserved.
 *
 * This library 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; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library 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 Lesser General Public License for more
 * details.
 */

package jorgediazest.util.data;

/**
 * @author Jorge Díaz
 */
public class DataBaseComparator implements DataComparator {

	public int compare(Data data1, Data data2) {

		if (data1.equals(data2)) {
			return 0;
		}

		return DataUtil.compareLongs(data1.hashCode(), data2.hashCode());
	}

	public boolean equals(Data data1, Data data2) {

		if (data1.hashCode() != data2.hashCode()) {
			return false;
		}

		return data1.getMap().equals(data2.getMap());
	}

	public boolean equalsAttributes(
		Data data1, Data data2, String attr1, String attr2, Object o1,
		Object o2) {

		if (DataUtil.isNull(o1)) {
			return DataUtil.isNull(o2);
		}

		if (DataUtil.isNull(o2)) {
			return false;
		}

		if (o1.equals(o2)) {
			return true;
		}

		int type1 = data1.getAttributeType(attr1);
		int type2 = data2.getAttributeType(attr2);

		if ((type1 != type2) || (type1 == 0) || (type2 == 0)) {
			o1 = DataUtil.castString(o1);
			o2 = DataUtil.castString(o2);

			return o1.equals(o2);
		}

		return false;
	}

	public boolean exact(Data data1, Data data2) {
		return equals(data1, data2);
	}

	@Override
	public String[] getExactAttributes() {
		return new String[0];
	}

	public Integer hashCode(Data data) {

		return data.getMap().hashCode();
	}

}
@@ -616,16 +616,112 @@
 .data;%0A%0A
+import com.liferay.portal.kernel.log.Log;%0Aimport com.liferay.portal.kernel.log.LogFactoryUtil;%0A%0A
 /**%0A * @
@@ -1260,44 +1260,102 @@
 %0A%0A%09%09
-if (DataUtil.isNull(o1)) %7B%0A%09%09%09return
+boolean equalsAttribute = false;%0A%0A%09%09boolean isNull1 = DataUtil.isNull(o1);%0A%09%09boolean isNull2 =
  Dat
@@ -1371,28 +1371,24 @@
 ull(o2);
-%0A%09%09%7D
 %0A%0A%09%09if (
 DataUtil
@@ -1383,59 +1383,107 @@
 if (
-DataUtil.
+isNull1 %7C%7C 
 isNull
-(o2)
+2
 ) %7B%0A%09%09%09
-return false;%0A%09%09%7D%0A%0A%09%09if (
+equalsAttribute = (isNull1 && isNull2);%0A%09%09%7D%0A%09%09else %7B%0A%09%09%09equalsAttribute = 
 o1.e
@@ -1495,33 +1495,40 @@
 (o2)
-) %7B
+;%0A
 %0A%09%09%09
-return true;%0A%09%09%7D%0A%0A
+if (!equalsAttribute) %7B%0A%09%09
 %09%09in
@@ -1568,16 +1568,18 @@
 attr1);%0A
+%09%09
 %09%09int ty
@@ -1614,24 +1614,26 @@
 (attr2);%0A%0A%09%09
+%09
+%09
 if ((type1 !
@@ -1679,16 +1679,18 @@
 )) %7B%0A%09%09%09
+%09%09
 o1 = Dat
@@ -1714,16 +1714,18 @@
 o1);%0A%09%09%09
+%09
+%09
 o2 = Dat
@@ -1754,48 +1754,288 @@
 %0A%09%09%09
-return o1.equals(o2);%0A%09%09%7D%0A%0A%09%09return fals
+%09%09equalsAttribute = o1.equals(o2);%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09if (_log.isDebugEnabled() && !(equalsAttribute)) %7B%0A%09%09%09_log.debug(%22data1=%22 + data1 + %22 data2=%22 + data2 + %22 attr1=%22 +%0A%09%09%09%09attr1 + %22 attr2=%22 + attr2 + %22 o1=%22 + o1 + %22 o2=%22 + o2 +%0A%09%09%09%09%22 are not equal%22);%0A%09%09%7D%0A%0A%09%09return equalsAttribut
 e;%0A%09
@@ -2277,9 +2277,86 @@
 ();%0A%09%7D%0A%0A
+%09private static Log _log = LogFactoryUtil.getLog(DataBaseComparator.class);%0A%0A
 %7D

Add log to DataBaseComparator.equalsAttributes when attributes are different