Skip to content

Commit

Permalink
OGM-1581 Investigate work necessary to upgrade remote Neo4j to Bolt >…
Browse files Browse the repository at this point in the history
…= 4.
  • Loading branch information
michael-simons committed Jul 15, 2021
1 parent 0beb890 commit 2de0c62
Show file tree
Hide file tree
Showing 16 changed files with 213 additions and 258 deletions.
2 changes: 1 addition & 1 deletion bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
<!-- Neo4j -->

<version.org.neo4j>3.4.11</version.org.neo4j>
<version.org.neo4j.driver>1.7.2</version.org.neo4j.driver>
<version.org.neo4j.driver>4.3.3</version.org.neo4j.driver>
<version.neo4j.org.scala-lang>2.11.11</version.neo4j.org.scala-lang>
<!-- See Parboiled dependency above -->
<!-- See Lucene dependency above -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@
import org.hibernate.ogm.model.spi.TupleSnapshot;
import org.hibernate.ogm.storedprocedure.ProcedureQueryParameters;
import org.neo4j.driver.internal.types.InternalTypeSystem;
import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.Statement;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Transaction;
import org.neo4j.driver.v1.Value;
import org.neo4j.driver.v1.exceptions.ClientException;
import org.neo4j.driver.v1.summary.ResultSummary;
import org.neo4j.driver.v1.types.Node;
import org.neo4j.driver.v1.types.Relationship;
import org.neo4j.driver.Record;
import org.neo4j.driver.Session;
import org.neo4j.driver.Query;
import org.neo4j.driver.Result;
import org.neo4j.driver.Transaction;
import org.neo4j.driver.Value;
import org.neo4j.driver.exceptions.ClientException;
import org.neo4j.driver.summary.ResultSummary;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Relationship;

/**
* Abstracts Hibernate OGM from Neo4j.
Expand Down Expand Up @@ -111,14 +111,14 @@ protected BoltNeo4jEntityQueries createNeo4jEntityQueries(EntityKeyMetadata enti
@Override
public ClosableIterator<Tuple> executeBackendQuery(BackendQuery<String> backendQuery, QueryParameters queryParameters, TupleContext tupleContext) {
Map<String, Object> parameters = getParameters( queryParameters );
String nativeQuery = buildNativeQuery( backendQuery, queryParameters );
Statement statement = new Statement( nativeQuery, parameters );
String cypher = buildNativeQuery( backendQuery, queryParameters );
Query nativeQuery = new Query( cypher, parameters );
if ( backendQuery.getSingleEntityMetadataInformationOrNull() != null ) {
EntityKeyMetadata entityKeyMetadata = backendQuery.getSingleEntityMetadataInformationOrNull().getEntityKeyMetadata();
BoltNeo4jEntityQueries queries = getEntityQueries( entityKeyMetadata, tupleContext );
Transaction transaction = transaction( tupleContext );
StatementResult result = transaction.run( statement );
validateNativeQuery( result );
Result result = transaction.run( nativeQuery );
validateResult( result );
List<EntityKey> entityKeys = new ArrayList<>();
while ( result.hasNext() ) {
Record record = result.next();
Expand All @@ -139,8 +139,8 @@ public ClosableIterator<Tuple> executeBackendQuery(BackendQuery<String> backendQ
}
else {
Transaction transaction = transaction( tupleContext );
StatementResult statementResult = transaction.run( statement );
validateNativeQuery( statementResult );
Result statementResult = transaction.run( nativeQuery );
validateResult( statementResult );
return new BoltNeo4jMapsTupleIterator( statementResult );
}
}
Expand All @@ -152,16 +152,16 @@ private boolean isProjection(Value value) {
@Override
public int executeBackendUpdateQuery(BackendQuery<String> query, QueryParameters queryParameters, TupleContext tupleContext) {
Map<String, Object> parameters = getParameters( queryParameters );
String nativeQuery = buildNativeQuery( query, queryParameters );
Statement statement = new Statement( nativeQuery, parameters );
String cypher = buildNativeQuery( query, queryParameters );
Query nativeQuery = new Query( cypher, parameters );
Transaction transaction = transaction( tupleContext );
StatementResult statementResult = transaction.run( statement );
validateNativeQuery( statementResult );
Result statementResult = transaction.run( nativeQuery );
validateResult( statementResult );
ResultSummary summary = statementResult.consume();
return updatesCount( summary );
}

private void validateNativeQuery(StatementResult result) {
private void validateResult(Result result) {
try {
result.hasNext();
}
Expand Down Expand Up @@ -281,19 +281,19 @@ public void insertOrUpdateTuple(EntityKey key, TuplePointer tuplePointer, TupleC
Tuple tuple = tuplePointer.getTuple();
final Map<String, EntityKey> toOneAssociations = new HashMap<>();
Map<String, Object> properties = new HashMap<>();
List<Statement> statements = new ArrayList<>();
applyTupleOperations( key, tuple, properties, toOneAssociations, statements, tuple.getOperations(), tupleContext, tupleContext.getTransactionContext() );
List<Query> queries = new ArrayList<>();
applyTupleOperations( key, tuple, properties, toOneAssociations, queries, tuple.getOperations(), tupleContext, tupleContext.getTransactionContext() );
if ( SnapshotType.INSERT.equals( tuple.getSnapshotType() ) ) {
// Insert new node
Statement statement = getEntityQueries( key.getMetadata(), tupleContext ).getCreateEntityWithPropertiesQueryStatement( key.getColumnValues(), properties );
statements.add( 0, statement );
Query query = getEntityQueries( key.getMetadata(), tupleContext ).getCreateEntityWithPropertiesQueryStatement( key.getColumnValues(), properties );
queries.add( 0, query );
}
else {
updateTuple( key, statements, properties, tupleContext );
updateTuple( key, queries, properties, tupleContext );
}
saveToOneAssociations( statements, key, toOneAssociations, tupleContext );
saveToOneAssociations( queries, key, toOneAssociations, tupleContext );
try {
runAll( transaction( tupleContext ), statements );
runAll( transaction( tupleContext ), queries );
tuple.setSnapshotType( SnapshotType.UPDATE );
}
catch (ClientException e) {
Expand All @@ -306,14 +306,14 @@ public void insertOrUpdateTuple(EntityKey key, TuplePointer tuplePointer, TupleC
}
}

private void runAll(Transaction tx, List<Statement> statements) {
for ( Statement statement : statements ) {
StatementResult result = tx.run( statement );
private void runAll(Transaction tx, List<Query> statements) {
for ( Query statement : statements ) {
Result result = tx.run( statement );
validate( result );
}
}

private void validate(StatementResult result) {
private void validate(Result result) {
result.hasNext();
}

Expand All @@ -327,49 +327,49 @@ private HibernateException extractException(EntityKey key, ClientException excep
}
}

private void updateTuple(EntityKey key, List<Statement> statements, Map<String, Object> properties, TupleContext tupleContext) {
private void updateTuple(EntityKey key, List<Query> queries, Map<String, Object> properties, TupleContext tupleContext) {
if ( !properties.isEmpty() ) {
Statement statement = getEntityQueries( key.getMetadata(), tupleContext ).getUpdateEntityPropertiesStatement( key.getColumnValues(), properties );
statements.add( statement );
Query statement = getEntityQueries( key.getMetadata(), tupleContext ).getUpdateEntityPropertiesStatement( key.getColumnValues(), properties );
queries.add( statement );
}
}

private void applyTupleOperations(EntityKey entityKey, Tuple tuple, Map<String, Object> node, Map<String, EntityKey> toOneAssociations, List<Statement> statements, Set<TupleOperation> operations, TupleContext tupleContext, TransactionContext transactionContext) {
private void applyTupleOperations(EntityKey entityKey, Tuple tuple, Map<String, Object> node, Map<String, EntityKey> toOneAssociations, List<Query> queries, Set<TupleOperation> operations, TupleContext tupleContext, TransactionContext transactionContext) {
Set<String> processedAssociationRoles = new HashSet<String>();

for ( TupleOperation operation : operations ) {
applyOperation( entityKey, tuple, node, toOneAssociations, statements, operation, tupleContext, transactionContext, processedAssociationRoles );
applyOperation( entityKey, tuple, node, toOneAssociations, queries, operation, tupleContext, transactionContext, processedAssociationRoles );
}
}

private void applyOperation(EntityKey entityKey, Tuple tuple, Map<String, Object> node, Map<String, EntityKey> toOneAssociations, List<Statement> statements, TupleOperation operation, TupleContext tupleContext, TransactionContext transactionContext, Set<String> processedAssociationRoles) {
private void applyOperation(EntityKey entityKey, Tuple tuple, Map<String, Object> node, Map<String, EntityKey> toOneAssociations, List<Query> queries, TupleOperation operation, TupleContext tupleContext, TransactionContext transactionContext, Set<String> processedAssociationRoles) {
switch ( operation.getType() ) {
case PUT:
putTupleOperation( entityKey, tuple, node, toOneAssociations, statements, operation, tupleContext, processedAssociationRoles );
putTupleOperation( entityKey, tuple, node, toOneAssociations, queries, operation, tupleContext, processedAssociationRoles );
break;
case PUT_NULL:
case REMOVE:
removeTupleOperation( entityKey, node, operation, statements, tupleContext, transactionContext, processedAssociationRoles );
removeTupleOperation( entityKey, node, operation, queries, tupleContext, transactionContext, processedAssociationRoles );
break;
}
}

private void saveToOneAssociations(List<Statement> statements, EntityKey key, final Map<String, EntityKey> toOneAssociations, TupleContext tupleContext) {
private void saveToOneAssociations(List<Query> statements, EntityKey key, final Map<String, EntityKey> toOneAssociations, TupleContext tupleContext) {
for ( Map.Entry<String, EntityKey> entry : toOneAssociations.entrySet() ) {
Statement statement = getEntityQueries( key.getMetadata(), tupleContext ).getUpdateOneToOneAssociationStatement( entry.getKey(), key.getColumnValues(), entry.getValue().getColumnValues() );
Query statement = getEntityQueries( key.getMetadata(), tupleContext ).getUpdateOneToOneAssociationStatement( entry.getKey(), key.getColumnValues(), entry.getValue().getColumnValues() );
statements.add( statement );
}
}

private void removeTupleOperation(EntityKey entityKey, Map<String, Object> ownerNode, TupleOperation operation, List<Statement> statements, TupleContext tupleContext, TransactionContext transactionContext, Set<String> processedAssociationRoles) {
private void removeTupleOperation(EntityKey entityKey, Map<String, Object> ownerNode, TupleOperation operation, List<Query> statements, TupleContext tupleContext, TransactionContext transactionContext, Set<String> processedAssociationRoles) {
if ( !tupleContext.getTupleTypeContext().isPartOfAssociation( operation.getColumn() ) ) {
if ( isPartOfRegularEmbedded( entityKey.getColumnNames(), operation.getColumn() ) ) {
// Embedded node
Statement statement = getEntityQueries( entityKey.getMetadata(), tupleContext ).removeEmbeddedColumnStatement( entityKey.getColumnValues(), operation.getColumn(), transaction( tupleContext ) );
Query statement = getEntityQueries( entityKey.getMetadata(), tupleContext ).removeEmbeddedColumnStatement( entityKey.getColumnValues(), operation.getColumn(), transaction( tupleContext ) );
statements.add( statement );
}
else {
Statement statement = getEntityQueries( entityKey.getMetadata(), tupleContext ).removeColumnStatement( entityKey.getColumnValues(), operation.getColumn(), transaction( tupleContext ) );
Query statement = getEntityQueries( entityKey.getMetadata(), tupleContext ).removeColumnStatement( entityKey.getColumnValues(), operation.getColumn(), transaction( tupleContext ) );
statements.add( statement );
}
}
Expand All @@ -383,13 +383,13 @@ private void removeTupleOperation(EntityKey entityKey, Map<String, Object> owner
}

private void putTupleOperation(EntityKey entityKey, Tuple tuple, Map<String, Object> node, Map<String, EntityKey> toOneAssociations,
List<Statement> statements, TupleOperation operation, TupleContext tupleContext, Set<String> processedAssociationRoles) {
List<Query> statements, TupleOperation operation, TupleContext tupleContext, Set<String> processedAssociationRoles) {
if ( tupleContext.getTupleTypeContext().isPartOfAssociation( operation.getColumn() ) ) {
// the column represents a to-one association, map it as relationship
putOneToOneAssociation( entityKey, tuple, node, toOneAssociations, operation, tupleContext, processedAssociationRoles );
}
else if ( isPartOfRegularEmbedded( entityKey.getMetadata().getColumnNames(), operation.getColumn() ) ) {
Statement statement = getEntityQueries( entityKey.getMetadata(), tupleContext ).updateEmbeddedColumnStatement( entityKey.getColumnValues(), operation.getColumn(), operation.getValue() );
Query statement = getEntityQueries( entityKey.getMetadata(), tupleContext ).updateEmbeddedColumnStatement( entityKey.getColumnValues(), operation.getColumn(), operation.getValue() );
statements.add( statement );
}
else {
Expand Down Expand Up @@ -497,7 +497,7 @@ private void removeAssociationOperation(AssociationKey associationKey, Associati
* <p>
* the first time with the information related to the owner of the association and the {@link RowKey},
* the second time using the same {@link RowKey} but with the {@link AssociationKey} referring to the other side of the association.
* @param associatedEntityKeyMetadata
* @param associationKey
* @param action
*/
private void putAssociationOperation(AssociationKey associationKey, AssociationOperation action, AssociationContext associationContext) {
Expand Down Expand Up @@ -597,7 +597,7 @@ public ClosableIterator<Tuple> callStoredProcedure(
Map.Entry<String, Map<String, Object>> queryAndParams = buildProcedureQueryWithParams(
storedProcedureName, queryParameters );
Transaction transaction = transaction( tupleContext );
StatementResult result = transaction.run( queryAndParams.getKey(), queryAndParams.getValue() );
Result result = transaction.run( queryAndParams.getKey(), queryAndParams.getValue() );
try {
return new BoltNeo4jMapsTupleIterator( result );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import org.hibernate.ogm.dialect.spi.TupleTypeContext;
import org.hibernate.ogm.model.key.spi.AssociatedEntityKeyMetadata;
import org.hibernate.ogm.model.key.spi.EntityKeyMetadata;
import org.neo4j.driver.v1.Transaction;
import org.neo4j.driver.v1.types.Node;
import org.neo4j.driver.Transaction;
import org.neo4j.driver.types.Node;

/**
* Function required to get the associated nodes when building the tuple snapshot.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
import org.hibernate.ogm.model.key.spi.EntityKeyMetadata;
import org.hibernate.ogm.model.key.spi.RowKey;
import org.hibernate.ogm.util.impl.ArrayHelper;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Transaction;
import org.neo4j.driver.v1.types.Relationship;
import org.neo4j.driver.Result;
import org.neo4j.driver.Transaction;
import org.neo4j.driver.types.Relationship;

/**
* @author Davide D'Alto
Expand All @@ -36,11 +36,11 @@ public void removeAssociation(Transaction tx, AssociationKey associationKey) {
public Relationship findRelationship(Transaction tx, AssociationKey associationKey, RowKey rowKey) {
Object[] relationshipValues = relationshipValues( associationKey, rowKey );
Object[] queryValues = ArrayHelper.concat( associationKey.getEntityKey().getColumnValues(), relationshipValues );
StatementResult result = tx.run( findRelationshipQuery, params( queryValues ) );
Result result = tx.run( findRelationshipQuery, params( queryValues ) );
return relationship( result );
}

private Relationship relationship(StatementResult result) {
private Relationship relationship(Result result) {
if ( result.hasNext() ) {
return result.next().get( 0 ).asRelationship();
}
Expand All @@ -51,14 +51,14 @@ public Relationship createRelationshipForEmbeddedAssociation(Transaction tx, Ass
Object[] relationshipProperties) {
String query = initCreateEmbeddedAssociationQuery( associationKey, embeddedKey );
Object[] queryValues = createRelationshipForEmbeddedQueryValues( associationKey, embeddedKey, relationshipProperties );
StatementResult statementResult = tx.run( query, params( queryValues ) );
Result statementResult = tx.run( query, params( queryValues ) );
return relationship( statementResult );
}

public Relationship createRelationship(Transaction tx, Object[] ownerKeyValues, Object[] targetKeyValues, Object[] relationshipProperties) {
Object[] concat = ArrayHelper.concat( Arrays.asList( ownerKeyValues, targetKeyValues, relationshipProperties ) );
Map<String, Object> params = params( concat );
StatementResult statementResult = tx.run( createRelationshipQuery, params );
Result statementResult = tx.run( createRelationshipQuery, params );
return relationship( statementResult );
}

Expand Down

0 comments on commit 2de0c62

Please sign in to comment.