The problem that I’m running into is that after I make an AutoIndex index a certain property, I can add a key/value pair and the index won’t show that it’s there. I’m relatively new to neo4j so my concept of what this class is supposed to do might be wrong. The test code creates an impermanent graph database, instantiates my data service class with it, and then creates a user. When the data service class is instantiated, that’s when the properties are added to the AutoIndex. You can see inside the createUser() function, I’ve printed out the user that I’ve just created and should be in the AutoIndex, but it prints null.
This is the code I’m testing:
@Before
public void setup() throws IOException {
graphDb = new ImpermanentGraphDatabase();
Transaction tx = graphDb.beginTx();
try {
nA = graphDb.createNode();
nB = graphDb.createNode();
packetA = graphDb.createNode();
packetB = graphDb.createNode();
dataService = new DataServiceImpl(graphDb);
tx.success();
}
finally
{
tx.finish();
}
}
/****************** Test User Creation Functionality *******************/
@Test
public void createUser() throws ExistsException {
Transaction tx = graphDb.beginTx();
try {
UserWrapper user = (UserWrapper) dataService.createUser(BigInteger.valueOf(1));
tx.success();
}
finally {
tx.finish();
}
}
Here’s the code in DataServiceImpl:
/**
* Node property keys that should be auto-indexed.
*/
private static final Set<String> NODE_KEYS_INDEXABLE = new HashSet<String>(
Arrays.asList(new String[] { UserWrapper.KEY_IDENTIFIER }));
/**
* Relationship property keys that should be auto-index.
*/
private static final Set<String> REL_KEYS_INDEXABLE = new HashSet<String>(
Arrays.asList(new String[] { SentWrapper.TIME_PROP }));
private void initIndices() {
/* Get the auto-indexers */
AutoIndexer<Node> nodeAutoIndexer = this.graphDb.index()
.getNodeAutoIndexer();
RelationshipAutoIndexer relAutoIndexer = this.graphDb.index()
.getRelationshipAutoIndexer();
this.updateIndexProperties(nodeAutoIndexer,
DataServiceImpl.NODE_KEYS_INDEXABLE);
this.nodeIndex = nodeAutoIndexer.getAutoIndex();
this.updateIndexProperties(relAutoIndexer,
DataServiceImpl.REL_KEYS_INDEXABLE);
this.relIndex = relAutoIndexer.getAutoIndex();
}
/**
* Sets the indexed properties of an {@link AutoIndexer} to the specified
* set, removing old properties and adding new ones.
*
* @param autoIndexer
* the AutoIndexer to update.
* @param properties
* the properties to be indexed.
* @return autoIndexer, this given AutoIndexer (useful for chaining calls.)
*/
private <T extends PropertyContainer> AutoIndexer<T> updateIndexProperties(
AutoIndexer<T> autoIndexer, Set<String> properties) {
Set<String> indexedProps = autoIndexer.getAutoIndexedProperties();
// Remove unneeded properties.
for (String prop : difference(indexedProps, properties)) {
autoIndexer.stopAutoIndexingProperty(prop);
}
// Add new properties.
for (String prop : difference(properties, indexedProps)) {
autoIndexer.startAutoIndexingProperty(prop);
}
// Enable the index, if needed.
if (!autoIndexer.isEnabled()) {
autoIndexer.setEnabled(true);
}
return autoIndexer;
}
public User createUser(BigInteger identifier) throws ExistsException {
// Verify that user doesn't already exist.
if (this.nodeIndex.get(UserWrapper.KEY_IDENTIFIER, identifier).getSingle() != null) {
throw new ExistsException("User with identifier '" + identifier.toString() + "' already exists.");
}
// Create new user.
final Node userNode = graphDb.createNode();
final User user = new UserWrapper(userNode);
user.setIdentifier(identifier);
Node userNode2 = this.nodeIndex.get(UserWrapper.KEY_IDENTIFIER, identifier).getSingle();
System.out.println(userNode2);
userParent.getNode().createRelationshipTo(userNode, NodeRelationships.PARENT);
return user;
}
Here’s the code in UserWrapper:
/**
* Mapping to neo4j key for the identifier property.
*/
//Changed to public in order to test in Test class
static final String KEY_IDENTIFIER = "identifier";
@Override
public void setIdentifier(BigInteger newIdentity) {
neo4jNode.setProperty(KEY_IDENTIFIER, newIdentity.toByteArray());
}
Where do you add the second user? By running the test twice? Then
ImpermanentGraphDatabasewill have deleted all data (as it is intended for testing) before the second run. The indexing happens at commit time, and aggregates all changes during the transaction, that’s why you don’t see it within the tx (userNode2). If you’d like to you can add this check to the test (see below).From your code it is also not visible where you call the
initIndices, could you please indicate the place? Please also verify that the auto-indexer is indexing the correct properties.Try to change your test to, then the second call should throw the exception: