Skip to content

Commit

Permalink
Default transaction is not cleared from thread local when the query f…
Browse files Browse the repository at this point in the history
…ails. Fixes #393
  • Loading branch information
nmervaillie committed Sep 5, 2017
1 parent 406cf4f commit 5d40ac0
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.exceptions.ClientException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.neo4j.ogm.config.ObjectMapperFactory;
import org.neo4j.ogm.drivers.bolt.response.GraphModelResponse;
import org.neo4j.ogm.drivers.bolt.response.GraphRowModelResponse;
Expand All @@ -35,12 +38,16 @@
import org.neo4j.ogm.model.GraphRowListModel;
import org.neo4j.ogm.model.RestModel;
import org.neo4j.ogm.model.RowModel;
import org.neo4j.ogm.request.*;
import org.neo4j.ogm.request.DefaultRequest;
import org.neo4j.ogm.request.GraphModelRequest;
import org.neo4j.ogm.request.GraphRowListModelRequest;
import org.neo4j.ogm.request.Request;
import org.neo4j.ogm.request.RestModelRequest;
import org.neo4j.ogm.request.RowModelRequest;
import org.neo4j.ogm.request.Statement;
import org.neo4j.ogm.response.EmptyResponse;
import org.neo4j.ogm.response.Response;
import org.neo4j.ogm.transaction.TransactionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author vince
Expand Down Expand Up @@ -85,15 +92,14 @@ public Response<RowModel> execute(DefaultRequest query) {
String[] columns = null;
for (Statement statement : query.getStatements()) {
StatementResult result = executeRequest(statement);
if (columns == null) {
List<String> columnSet = result.keys();
columns = columnSet.toArray(new String[columnSet.size()]);
}
RowModelResponse rowModelResponse = new RowModelResponse(result, transactionManager);
RowModel model;
while ((model = rowModelResponse.next()) != null) {
rowmodels.add(model);
}
if (columns == null) {
columns = rowModelResponse.columns();
}
result.consume();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.exceptions.ClientException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.neo4j.ogm.drivers.bolt.transaction.BoltTransaction;
import org.neo4j.ogm.exception.CypherException;
import org.neo4j.ogm.response.Response;
import org.neo4j.ogm.transaction.TransactionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author Luanne Misquitta
Expand Down Expand Up @@ -69,13 +70,25 @@ public void close() {

@Override
public String[] columns() {
if (result.hasNext()) {
Record record = result.peek();
if (record != null) {
Set<String> columns = result.peek().asMap().keySet();
return columns.toArray(new String[columns.size()]);
try {
if (result.hasNext()) {
Record record = result.peek();
if (record != null) {
Set<String> columns = result.peek().asMap().keySet();
return columns.toArray(new String[columns.size()]);
}
}
} catch (ClientException ce) {
// exception may occur if records has not been fetched yet
// should we catch other things than ClientException ?
BoltTransaction tx = (BoltTransaction) transactionManager.getCurrentTransaction();
if (tx != null) {
tx.rollback();
}
LOGGER.debug("Error executing Cypher: {}, {}", ce.code(), ce.getMessage());
throw new CypherException("Error executing Cypher", ce, ce.code(), ce.getMessage());
}

return new String[0];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.neo4j.ogm.annotation.RelationshipEntity;
import org.neo4j.ogm.context.MappedRelationship;
import org.neo4j.ogm.context.MappingContext;
import org.neo4j.ogm.context.TransientRelationship;
import org.neo4j.ogm.cypher.compiler.CompileContext;
import org.neo4j.ogm.cypher.compiler.Compiler;
import org.neo4j.ogm.exception.CypherException;
import org.neo4j.ogm.metadata.ClassInfo;
import org.neo4j.ogm.metadata.FieldInfo;
import org.neo4j.ogm.model.RowModel;
Expand All @@ -34,8 +38,6 @@
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.transaction.AbstractTransaction;
import org.neo4j.ogm.transaction.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Plans request execution and processes the response.
Expand Down Expand Up @@ -289,18 +291,22 @@ private void executeSave(CompileContext context, boolean transactionRequired) {
}
}
}

if (transactionRequired && newTransaction) {
tx.commit();
tx.close();
}
} catch (Exception e) {
} catch (CypherException e) {
// all tx management logic should be here in case of error. At the moment it is
// split in various parts of the drivers. Needs to be refactored in next major version.
// This is intended to fix #393. Replacing previous workaround to make HTTP work
if (transactionRequired && newTransaction) {
tx.rollback();
tx.close();
throw e;
}
}

if (transactionRequired && newTransaction) {
tx.commit();
tx.close();
}

//Update the mapping context now that the request is successful
updateNodeEntities(context, session, entityReferenceMappings);
updateRelationshipEntities(context, session, relReferenceMappings);
Expand Down

0 comments on commit 5d40ac0

Please sign in to comment.