在 Spring Data Neo4j 4 中发送并发请求以持久化实体和关系时抛出 NPE
NPE is thrown when sending concurrent requests to persist entities and relationships in Spring Data Neo4j 4
我正在持久化一个包含与其他几个实体的关系的节点实体。当我一次做一个时,这种坚持工作得很好,但是如果我 运行 同时这样做,我会得到 NPE
组织neo4j.ogm.mapper.EntityGraphMapper
java.lang.NullPointerException: null
at org.neo4j.ogm.mapper.EntityGraphMapper.updateRelationship(EntityGraphMapper.java:618) ~[neo4j-ogm-1.1.2.jar:na]
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelationshipEntity(EntityGraphMapper.java:481) ~[neo4j-ogm-1.1.2.jar:na]
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:330) ~[neo4j-ogm-1.1.2.jar:na]
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:265) ~[neo4j-ogm-1.1.2.jar:na]
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:158) ~[neo4j-ogm-1.1.2.jar:na]
这是我的节点实体的症结所在:
@NodeEntity
public class Post {
@Relationship(type = "POST_BY_USER", direction = Relationship.INCOMING)
User poster;
@Relationship(type = "POST_TO_STORE", direction = Relationship.OUTGOING)
Store toStore;
@Relationship(type = "POST_PRODUCT", direction = Relationship.INCOMING)
Product product;
@Relationship(type = "POST_INSPIRATION", direction = Relationship.INCOMING)
Product_Inspiration productInspiration;
}
我尝试坚持使用带有 (@Transactional) 的 GraphRepository 以及使用带有事务的会话,在这两种情况下,我都遇到了相同的并发问题。
有人可以告诉我如何解决这个问题吗?因为我在轰炸并发请求时遇到了这个问题,所以我不确定这是否与代码流有关。
根据 Vince 关于如何发送并发请求的代码的要求,我将 axon cqrs 框架与 Play 一起使用,我将多个并发请求发送到我的 Play 应用程序的其余部分 API,它通过 axon 调用对 Neo4j 的并发写入后产品方法。
这是我编写代码的样子。
def postProduct(productId: ProductId, product2Post: Product2Post): Post = workNLogOnFail(
doPost(productId, product2Post),
"postProduct"
)
private def doPost(productId: ProductId, product2Post: Product2Post): Post = {
val product: Product = configureDomainEntity(productId, product2Post)
val storeId: StoreId = storeService1.findOrCreateStore(product2Post.host)
val post: Post = commonService.configurePost(product2Post.commonData2Post.relationInfo, isProduct = true) { (x: Post) =>
x.setToStore(storeService1.updateStoreForProductPost(x, storeId))
x.setProduct(product)
}
val persistedPost = xtPostProduct(product, post)
commonService.addUrlMapping(product2Post.commonData2Post, productId.identifier)
persistedPost
}
private def xtPostProduct(product: Product, post: Post): Post = {
Try {
val tx: Transaction = session.beginTransaction()
logger.debug(s"saving product")
// session.save(product)
logger.debug(s"updating user")
// session.save(post.getPoster)
logger.debug(s"posting product")
session.save(post)
tx.commit()
post
}.get
}
我在 xtPostProduct 方法中尝试了带有 GraphRepository 的 @Transanctional 以及会话。
想通了。问题是由于 spring DI 连接,我的会话或存储库使用的会话不是每个工作单元。由于我通过 Axon 调用数据库操作,因此使用范围为 "session" 的会话 Bean 的正常方法将不起作用。我已经恢复为我需要处理的每个 Axon 事件手动创建会话。因为本质上对我来说,那是我的工作单位!!
我正在持久化一个包含与其他几个实体的关系的节点实体。当我一次做一个时,这种坚持工作得很好,但是如果我 运行 同时这样做,我会得到 NPE 组织neo4j.ogm.mapper.EntityGraphMapper
java.lang.NullPointerException: null
at org.neo4j.ogm.mapper.EntityGraphMapper.updateRelationship(EntityGraphMapper.java:618) ~[neo4j-ogm-1.1.2.jar:na]
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelationshipEntity(EntityGraphMapper.java:481) ~[neo4j-ogm-1.1.2.jar:na]
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:330) ~[neo4j-ogm-1.1.2.jar:na]
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:265) ~[neo4j-ogm-1.1.2.jar:na]
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:158) ~[neo4j-ogm-1.1.2.jar:na]
这是我的节点实体的症结所在:
@NodeEntity
public class Post {
@Relationship(type = "POST_BY_USER", direction = Relationship.INCOMING)
User poster;
@Relationship(type = "POST_TO_STORE", direction = Relationship.OUTGOING)
Store toStore;
@Relationship(type = "POST_PRODUCT", direction = Relationship.INCOMING)
Product product;
@Relationship(type = "POST_INSPIRATION", direction = Relationship.INCOMING)
Product_Inspiration productInspiration;
}
我尝试坚持使用带有 (@Transactional) 的 GraphRepository 以及使用带有事务的会话,在这两种情况下,我都遇到了相同的并发问题。
有人可以告诉我如何解决这个问题吗?因为我在轰炸并发请求时遇到了这个问题,所以我不确定这是否与代码流有关。
根据 Vince 关于如何发送并发请求的代码的要求,我将 axon cqrs 框架与 Play 一起使用,我将多个并发请求发送到我的 Play 应用程序的其余部分 API,它通过 axon 调用对 Neo4j 的并发写入后产品方法。 这是我编写代码的样子。
def postProduct(productId: ProductId, product2Post: Product2Post): Post = workNLogOnFail(
doPost(productId, product2Post),
"postProduct"
)
private def doPost(productId: ProductId, product2Post: Product2Post): Post = {
val product: Product = configureDomainEntity(productId, product2Post)
val storeId: StoreId = storeService1.findOrCreateStore(product2Post.host)
val post: Post = commonService.configurePost(product2Post.commonData2Post.relationInfo, isProduct = true) { (x: Post) =>
x.setToStore(storeService1.updateStoreForProductPost(x, storeId))
x.setProduct(product)
}
val persistedPost = xtPostProduct(product, post)
commonService.addUrlMapping(product2Post.commonData2Post, productId.identifier)
persistedPost
}
private def xtPostProduct(product: Product, post: Post): Post = {
Try {
val tx: Transaction = session.beginTransaction()
logger.debug(s"saving product")
// session.save(product)
logger.debug(s"updating user")
// session.save(post.getPoster)
logger.debug(s"posting product")
session.save(post)
tx.commit()
post
}.get
}
我在 xtPostProduct 方法中尝试了带有 GraphRepository 的 @Transanctional 以及会话。
想通了。问题是由于 spring DI 连接,我的会话或存储库使用的会话不是每个工作单元。由于我通过 Axon 调用数据库操作,因此使用范围为 "session" 的会话 Bean 的正常方法将不起作用。我已经恢复为我需要处理的每个 Axon 事件手动创建会话。因为本质上对我来说,那是我的工作单位!!