@@ -104,6 +104,15 @@ public class EntityStore
104
104
private boolean initialized = false ;
105
105
private boolean cacheMethodValues = false ;
106
106
107
+ /**
108
+ * Whether to expect the return value from Statement.executeUpdate() to indicate
109
+ * whether the row was actually changed. If using MySQL and the connect string
110
+ * has useAffectedRows=true set on it, then this can be used. It defaults to
111
+ * false because it is MySQL-specific and requires explicitly enabling this in
112
+ * the connect string.
113
+ */
114
+ private boolean useAffectedRows = false ;
115
+
107
116
/**
108
117
* The registered method value caches. These allow you to quickly find
109
118
* entities by the value of a given field.
@@ -201,6 +210,14 @@ public void configure(EnhancedProperties props)
201
210
cacheMethodValues = props .getBoolean ("CacheController.CacheMethodValues" , false );
202
211
cacheMethodValues = props .getBoolean ("EntityStore.CacheMethodValues" , cacheMethodValues );
203
212
213
+ // Whether to expect the return value from Statement.executeUpdate() to indicate
214
+ // whether the row was actually changed.
215
+ useAffectedRows = props .getBoolean ("EntityStore.UseAffectedRows" , useAffectedRows );
216
+ if (useAffectedRows )
217
+ {
218
+ log .warn ("EntityStore.UseAffectedRows is enabled, which REQUIRES that the database connection be configured so update statements return the count of affected rows. If unsure, disable this." );
219
+ }
220
+
204
221
methodValueCaches = new HashMap <>();
205
222
206
223
// This should only happen when the application is reconfigured.
@@ -1061,20 +1078,25 @@ public <T extends Identifiable> void put(T entity)
1061
1078
throw new ControllerError ("Cannot put null entity." );
1062
1079
}
1063
1080
1064
- getGroupSafe ((Class <T >)entity .getClass ()).put (entity );
1065
-
1066
- // Update method value caches.
1067
- final MethodValueCache <?> methodValueCache = methodValueCaches .get (entity .getClass ());
1068
- if (methodValueCache != null )
1069
- {
1070
- methodValueCache .update (entity .getId ());
1071
- }
1072
-
1073
- // Notify the listeners.
1074
- final CacheListener [] toNotify = listeners ;
1075
- for (CacheListener listener : toNotify )
1081
+ int rowsUpdated = getGroupSafe ((Class <T >)entity .getClass ()).put (entity );
1082
+
1083
+ // If useAffectedRows is enabled, then only update the methodValueCache and
1084
+ // notify the listeners if an actual change was persisted.
1085
+ if (!useAffectedRows || rowsUpdated > 0 )
1076
1086
{
1077
- listener .cacheObjectExpired (entity .getClass (), entity .getId ());
1087
+ // Update method value caches.
1088
+ final MethodValueCache <?> methodValueCache = methodValueCaches .get (entity .getClass ());
1089
+ if (methodValueCache != null )
1090
+ {
1091
+ methodValueCache .update (entity .getId ());
1092
+ }
1093
+
1094
+ // Notify the listeners.
1095
+ final CacheListener [] toNotify = listeners ;
1096
+ for (CacheListener listener : toNotify )
1097
+ {
1098
+ listener .cacheObjectExpired (entity .getClass (), entity .getId ());
1099
+ }
1078
1100
}
1079
1101
}
1080
1102
@@ -1631,28 +1653,33 @@ public <T extends Identifiable> void putAll(Collection<T> objects)
1631
1653
{
1632
1654
Class <T > type = entry .getKey ();
1633
1655
Collection <T > collection = entry .getValue ();
1634
-
1656
+
1635
1657
// Update the group.
1636
- getGroupSafe (type ).putAll (collection );
1637
-
1638
- // Update method value caches.
1639
- MethodValueCache <T > methodValueCache =
1640
- (MethodValueCache <T >)methodValueCaches .get (type );
1641
- if (methodValueCache != null )
1658
+ int rowsUpdated = getGroupSafe (type ).putAll (collection );
1659
+
1660
+ // If useAffectedRows is enabled, then only update the methodValueCache and
1661
+ // notify the listeners if an actual change was persisted.
1662
+ if (!useAffectedRows || rowsUpdated > 0 )
1642
1663
{
1643
- for (T object : collection )
1664
+ // Update method value caches.
1665
+ MethodValueCache <T > methodValueCache =
1666
+ (MethodValueCache <T >)methodValueCaches .get (type );
1667
+ if (methodValueCache != null )
1644
1668
{
1645
- methodValueCache .update (object .getId ());
1669
+ for (T object : collection )
1670
+ {
1671
+ methodValueCache .update (object .getId ());
1672
+ }
1646
1673
}
1647
- }
1648
-
1649
- // Notify the listeners.
1650
- final CacheListener [] toNotify = listeners ;
1651
- for (CacheListener listener : toNotify )
1652
- {
1653
- for (T object : collection )
1674
+
1675
+ // Notify the listeners.
1676
+ final CacheListener [] toNotify = listeners ;
1677
+ for (CacheListener listener : toNotify )
1654
1678
{
1655
- listener .cacheObjectExpired (object .getClass (), object .getId ());
1679
+ for (T object : collection )
1680
+ {
1681
+ listener .cacheObjectExpired (object .getClass (), object .getId ());
1682
+ }
1656
1683
}
1657
1684
}
1658
1685
}
0 commit comments