@Override protected ConstraintDefinition obtainEntityInTransaction( GraphDatabaseService graphDatabaseService) { return graphDatabaseService .schema() .constraintFor(DynamicLabel.label("Label")) .assertPropertyIsUnique("property") .create(); }
@Test public void shouldUseDynamicPropertiesToIndexANodeWhenAddedAlongsideExistingPropertiesInASeparateTransaction() throws Exception { // Given GraphDatabaseService beansAPI = dbRule.getGraphDatabaseAPI(); // When long id; { try (Transaction tx = beansAPI.beginTx()) { Node myNode = beansAPI.createNode(); id = myNode.getId(); myNode.setProperty("key0", true); myNode.setProperty("key1", true); tx.success(); } } { IndexDefinition indexDefinition; try (Transaction tx = beansAPI.beginTx()) { indexDefinition = beansAPI.schema().indexFor(LABEL1).on("key2").create(); tx.success(); } waitForIndex(beansAPI, indexDefinition); } Node myNode; { try (Transaction tx = beansAPI.beginTx()) { myNode = beansAPI.getNodeById(id); myNode.addLabel(LABEL1); myNode.setProperty("key2", LONG_STRING); myNode.setProperty("key3", LONG_STRING); tx.success(); } } // Then assertThat(myNode, inTx(beansAPI, hasProperty("key2").withValue(LONG_STRING))); assertThat(myNode, inTx(beansAPI, hasProperty("key3").withValue(LONG_STRING))); assertThat( findNodesByLabelAndProperty(LABEL1, "key2", LONG_STRING, beansAPI), containsOnly(myNode)); }
/* This test is a bit interesting. It tests a case where we've got a property that sits in one * property block and the value is of a long type. So given that plus that there's an index for that * label/property, do an update that changes the long value into a value that requires two property blocks. * This is interesting because the transaction logic compares before/after views per property record and * not per node as a whole. * * In this case this change will be converted into one "add" and one "remove" property updates instead of * a single "change" property update. At the very basic level it's nice to test for this corner-case so * that the externally observed behavior is correct, even if this test doesn't assert anything about * the underlying add/remove vs. change internal details. */ @Test public void shouldInterpretPropertyAsChangedEvenIfPropertyMovesFromOneRecordToAnother() throws Exception { // GIVEN GraphDatabaseService beansAPI = dbRule.getGraphDatabaseAPI(); long smallValue = 10L, bigValue = 1L << 62; Node myNode; { try (Transaction tx = beansAPI.beginTx()) { myNode = beansAPI.createNode(LABEL1); myNode.setProperty("pad0", true); myNode.setProperty("pad1", true); myNode.setProperty("pad2", true); // Use a small long here which will only occupy one property block myNode.setProperty("key", smallValue); tx.success(); } } { IndexDefinition indexDefinition; try (Transaction tx = beansAPI.beginTx()) { indexDefinition = beansAPI.schema().indexFor(LABEL1).on("key").create(); tx.success(); } waitForIndex(beansAPI, indexDefinition); } // WHEN try (Transaction tx = beansAPI.beginTx()) { // A big long value which will occupy two property blocks myNode.setProperty("key", bigValue); tx.success(); } // THEN assertThat( findNodesByLabelAndProperty(LABEL1, "key", bigValue, beansAPI), containsOnly(myNode)); assertThat(findNodesByLabelAndProperty(LABEL1, "key", smallValue, beansAPI), isEmpty()); }