Я пишу следующую процедуру для Neo4j 3.3.5:
/**
* This procedure provides best sell products from a category
*
* @param category the category node for which we are searching for best sell items
* @param limit limit of returned products count
*/
@Procedure(value = "bestSell.category")
@Description("Get best sell items from a specified category")
public Stream<OutputResult> bestSellForCategory(
@Name("category") Node category,
@Name(value = "limit", defaultValue = "20") Long limit) {
RelationshipType inCategoryType = RelationshipType.withName(IN_CATEGORY_RELATION);
RelationshipType recentlyOrderedType = RelationshipType.withName(RECENTLY_ORDERED_RELATION);
try {
List<Node> productsInCateogory = new ArrayList<>();
List<ScoredResult> scoredProducts = new ArrayList<>();
for (Relationship relationship : category.getRelationships(inCategoryType, Direction.INCOMING)) {
Node product = relationship.getOtherNode(category);
productsInCateogory.add(product);
}
productsInCateogory.parallelStream().forEach(node -> {
long i = 0;
for (Relationship ignored : node.getRelationships(recentlyOrderedType, Direction.INCOMING)) {
i++;
}
if (i != 0) {
scoredProducts.add(new ScoredResult((Long) node.getProperty(DOC_ID_PROPERTY), i));
}
});
return scoredProducts.stream().sorted((scoredResult, t1) -> (int) (scoredResult.score - t1.score)).limit(limit).map(s -> new OutputResult(s.docId));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
И это тест, который я написал для процедуры:
@Test
public void checkBestSellOutput() throws Throwable {
try (Driver driver = GraphDatabase.driver(neo4j.boltURI(), Config.build().withoutEncryption().toConfig())) {
Session session = driver.session();
try (Transaction tx = session.beginTransaction()) {
tx.run(
"MERGE (c:Category {categoryId:93})" +
"MERGE (p1:Product {docId:1})" +
"MERGE (p2:Product {docId:2})" +
"MERGE (p3:Product {docId:3})" +
"MERGE (p1)-[:IN_CATEGORY]->(c)" +
"MERGE (p2)-[:IN_CATEGORY]->(c)" +
"MERGE (p3)-[:IN_CATEGORY]->(c)" +
"MERGE (cust1:Customer {customerId:1})" +
"MERGE (cust2:Customer {customerId:2})" +
"MERGE (cust1)-[:RECENTLY_ORDERED]->(p1)" +
"MERGE (cust2)-[:RECENTLY_ORDERED]->(p1)" +
"MERGE (cust1)-[:RECENTLY_ORDERED]->(p2)");
tx.success();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
List<Record> results = session.run("MATCH (c:Category {categoryId: 93}) CALL bestSell.category(c, 20) YIELD docId RETURN docId").list();
assertThat(results.size(), equalTo(2));
}
}
Когда я пытаюсь запустить сборкус maven я получаю следующую ошибку: Не удалось вызвать процедуру bestSell.category
: Причина: java.lang.RuntimeException: Запрошенная операция не может быть выполнена, поскольку она должна быть выполнена в транзакции.Убедитесь, что вы помещаете свою операцию в соответствующий шаблон транзакции и повторите попытку.
Я много пробовал и не нашел ответа в документации.Как я могу это исправить?