private <R extends UpdatableRecord<R>> void testStoreWithOptimisticLock0( UpdatableTable<R> table, TableField<R, Integer> id, TableField<R, String> string) throws Exception { Factory create = create(new Settings().withExecuteWithOptimisticLocking(true)); // Storing without changing shouldn't execute any queries R record1 = create.fetchOne(table, id.equal(1)); assertEquals(0, record1.store()); assertEquals(0, record1.store()); // Succeed if there are no concurrency issues record1.setValue(string, "New Title 1"); assertEquals(1, record1.store()); assertEquals("New Title 1", create.fetchOne(table, id.equal(1)).getValue(string)); // Get new books R record2 = create.fetchOne(table, id.equal(1)); R record3 = create.fetchOne(table, id.equal(1)); // Still won't fail, but this will cause record3 to be stale record2.setValue(string, "New Title 2"); assertEquals(1, record2.store()); assertEquals("New Title 2", create.fetchOne(table, id.equal(1)).getValue(string)); // Storing without changing shouldn't execute any queries assertEquals(0, record3.store()); // This should fail as record3 is stale record3.setValue(string, "New Title 3"); try { record3.store(); fail(); } catch (DataChangedException expected) {} assertEquals("New Title 2", create.fetchOne(table, id.equal(1)).getValue(string)); // Refreshing first will work, though record3.refresh(); record3.setValue(string, "New Title 3"); assertEquals(1, record3.store()); assertEquals("New Title 3", create.fetchOne(table, id.equal(1)).getValue(string)); // Get new books R record4 = create.fetchOne(table, id.equal(1)); R record5 = create.fetchOne(table, id.equal(1)); // Delete the book assertEquals(1, record4.delete()); // Storing without changing shouldn't execute any queries assertEquals(0, record5.store()); // This should fail, as the database record no longer exists record5.setValue(string, "New Title 5"); try { record5.store(); fail(); } catch (DataChangedException expected) {} // Restore the book, refresh the copy, then it should work assertEquals(1, record4.store()); record5.refresh(); record5.setValue(string, "New Title 5"); assertEquals(1, record5.store()); assertEquals("New Title 5", create.fetchOne(table, id.equal(1)).getValue(string)); // Deleting the original should no longer be possible try { record4.delete(); fail(); } catch (DataChangedException expected) {} // Refreshing and deleting should work record4.refresh(); assertEquals(1, record4.delete()); // Now the other record cannot be deleted anymore try { record5.delete(); fail(); } catch (DataChangedException expected) {} }