|
26 | 26 | import org.apache.cayenne.query.ColumnSelect; |
27 | 27 | import org.apache.cayenne.query.EJBQLQuery; |
28 | 28 | import org.apache.cayenne.query.ObjectSelect; |
| 29 | +import org.apache.cayenne.query.PrefetchTreeNode; |
29 | 30 | import org.apache.cayenne.query.SelectById; |
30 | 31 | import org.apache.cayenne.runtime.CayenneRuntime; |
31 | 32 | import org.apache.cayenne.test.jdbc.TableHelper; |
@@ -1194,4 +1195,98 @@ public void insertTwoGenericVerticalInheritanceObjects() { |
1194 | 1195 | final List<Persistent> boys = ObjectSelect.query(Persistent.class, "GenBoy").select(env.context()); |
1195 | 1196 | assertEquals(1, boys.size()); |
1196 | 1197 | } |
| 1198 | + |
| 1199 | + private void updateFlattenedAttributeOfPrefetchedInheritedChild(int prefetchSemantics) throws SQLException { |
| 1200 | + TableHelper ivOtherTable = env.table("IV_OTHER", "ID"); |
| 1201 | + TableHelper ivBaseTable = env.table("IV_BASE", "ID", "NAME", "TYPE"); |
| 1202 | + TableHelper ivImplTable = env.table("IV_IMPL", "ID", "ATTR1", "OTHER3_ID"); |
| 1203 | + |
| 1204 | + ivOtherTable.insert(1); |
| 1205 | + ivBaseTable.insert(1, "name", "I"); |
| 1206 | + ivImplTable.insert(1, "attr1", 1); |
| 1207 | + |
| 1208 | + IvOther other = ObjectSelect.query(IvOther.class) |
| 1209 | + .prefetch(IvOther.IMPLS_WITH_INVERSE.getName(), prefetchSemantics) |
| 1210 | + .selectOne(env.context()); |
| 1211 | + |
| 1212 | + IvImpl impl = other.getImplsWithInverse().getFirst(); |
| 1213 | + assertEquals("attr1", impl.getAttr1()); |
| 1214 | + |
| 1215 | + impl.setAttr1("attr1-updated"); |
| 1216 | + env.context().commitChanges(); |
| 1217 | + |
| 1218 | + assertEquals(1, ivImplTable.getRowCount()); |
| 1219 | + ObjectContext cleanContext = runtime.newContext(); |
| 1220 | + IvImpl reread = SelectById.queryId(IvImpl.class, 1).selectOne(cleanContext); |
| 1221 | + assertEquals("attr1-updated", reread.getAttr1()); |
| 1222 | + } |
| 1223 | + |
| 1224 | + @Test |
| 1225 | + public void updateFlattenedAttributeOfInheritedChildJointPrefetch() throws SQLException { |
| 1226 | + updateFlattenedAttributeOfPrefetchedInheritedChild(PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS); |
| 1227 | + } |
| 1228 | + |
| 1229 | + @Test |
| 1230 | + public void updateFlattenedAttributeOfInheritedChildDisjointPrefetch() throws SQLException { |
| 1231 | + updateFlattenedAttributeOfPrefetchedInheritedChild(PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS); |
| 1232 | + } |
| 1233 | + |
| 1234 | + @Test |
| 1235 | + public void updateFlattenedAttributeOfInheritedChildDisjointByIdPrefetch() throws SQLException { |
| 1236 | + updateFlattenedAttributeOfPrefetchedInheritedChild(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS); |
| 1237 | + } |
| 1238 | + |
| 1239 | + @Test |
| 1240 | + public void updateFlattenedAttributeOfInheritedChildRepeatedSaveResolvedFromCachedSnapshot() throws SQLException { |
| 1241 | + TableHelper ivBaseTable = env.table("IV_BASE", "ID", "NAME", "TYPE"); |
| 1242 | + TableHelper ivImplTable = env.table("IV_IMPL", "ID", "ATTR1"); |
| 1243 | + |
| 1244 | + ivBaseTable.insert(1, "name", "I"); |
| 1245 | + ivImplTable.insert(1, "attr1"); |
| 1246 | + |
| 1247 | + // First request: loads the child fresh (cold cache) |
| 1248 | + // This rebuilds the shared cached snapshot for the child. |
| 1249 | + { |
| 1250 | + ObjectContext freshContext = runtime.newContext(); |
| 1251 | + IvImpl impl = Cayenne.objectForPK(freshContext, IvImpl.class, 1); |
| 1252 | + impl.setAttr1("attr1-first"); |
| 1253 | + freshContext.commitChanges(); |
| 1254 | + } |
| 1255 | + |
| 1256 | + // Second request: (new context, shared snapshot cache) |
| 1257 | + // objectForPK is served from the cached snapshot |
| 1258 | + { |
| 1259 | + ObjectContext freshContext = runtime.newContext(); |
| 1260 | + IvImpl impl = Cayenne.objectForPK(freshContext, IvImpl.class, 1); |
| 1261 | + impl.setAttr1("attr1-second"); |
| 1262 | + freshContext.commitChanges(); |
| 1263 | + } |
| 1264 | + |
| 1265 | + assertEquals(1, ivImplTable.getRowCount()); |
| 1266 | + ObjectContext cleanContext = runtime.newContext(); |
| 1267 | + IvImpl reread = SelectById.queryId(IvImpl.class, 1).selectOne(cleanContext); |
| 1268 | + assertEquals("attr1-second", reread.getAttr1()); |
| 1269 | + } |
| 1270 | + |
| 1271 | + @Test |
| 1272 | + public void updateFlattenedAttributeOfThreeLevelInheritanceChild() throws SQLException { |
| 1273 | + TableHelper ivRootTable = env.table("IV_ROOT", "ID", "DISCRIMINATOR"); |
| 1274 | + TableHelper ivSub1Table = env.table("IV_SUB1", "ID"); |
| 1275 | + TableHelper ivSub1Sub1Table = env.table("IV_SUB1_SUB1", "ID", "SUB1_SUB1_NAME"); |
| 1276 | + |
| 1277 | + ivRootTable.insert(1, "IvSub1Sub1"); |
| 1278 | + ivSub1Table.insert(1); |
| 1279 | + ivSub1Sub1Table.insert(1, "sub1sub1name"); |
| 1280 | + |
| 1281 | + IvSub1Sub1 sub1Sub1 = SelectById.queryId(IvSub1Sub1.class, 1).selectOne(env.context()); |
| 1282 | + assertEquals("sub1sub1name", sub1Sub1.getSub1Sub1Name()); |
| 1283 | + |
| 1284 | + sub1Sub1.setSub1Sub1Name("sub1sub1name-updated"); |
| 1285 | + env.context().commitChanges(); |
| 1286 | + |
| 1287 | + assertEquals(1, ivSub1Sub1Table.getRowCount()); |
| 1288 | + ObjectContext cleanContext = runtime.newContext(); |
| 1289 | + IvSub1Sub1 reread = SelectById.queryId(IvSub1Sub1.class, 1).selectOne(cleanContext); |
| 1290 | + assertEquals("sub1sub1name-updated", reread.getSub1Sub1Name()); |
| 1291 | + } |
1197 | 1292 | } |
0 commit comments