我目前正在开发一些由 SAP 系统触发的 Java (和带有 MySQL 连接的 JPA)的 Web 服务。为了简化我的问题,我将两个关键实体称为BlogEntry
和Comment
。一个BlogEntry
可以有多个Comments
。AComment
总是完全属于一个BlogEntry
。
所以我有三个服务(我不能也不想重新定义它们,因为它们是由我从 SAP 导出并使用并行与其他系统通信的 WSDL 定义的):CreateBlogEntry
,,,CreateComment
CreateCommentForUpcomingBlogEntry
它们被正确触发,并且当它们被单独调用时绝对没有CreateBlogEntry
问题CreateComment
。
但是:服务CreateCommentForUpcomingBlogEntry
会发送Comment
一个“外键”来识别“即将到来的” BlogEntry
。在内部,它还调用CreateBlogEntry
创建实际的BlogEntry
. 由于它们的异步特性,这两个服务是并发的。
所以我有两个选择:
- 创建一个虚拟对象
BlogEntry
并将其连接Comment
到它并更新BlogEntry
, 一旦CreateBlogEntry
“到达” - 等待
CreateBlogEntry
并将Comment
之后连接到新的BlogEntry
目前我正在尝试前者,但一旦两个服务都完全执行,我最终会得到两个 BlogEntries
. 其中一个只有ID
交付,CreateCommentForUpcomingBlogEntry
但它正确连接到Comment
(更多相反)。otherBlogEntry
具有所有其他信息(例如postDate
或body
),但 与Comment
它无关。
这是服务实现的代码片段CreateCommentForUpcomingBlogEntry
:
@EJB
private BlogEntryFacade blogEntryFacade;
@EJB
private CommentFacade commentFacade;
...
List<BlogEntry> blogEntries = blogEntryFacade.findById(request.getComment().getBlogEntryId().getValue());
BlogEntry persistBlogEntry;
if (blogEntries.isEmpty()) {
persistBlogEntry = new BlogEntry();
persistBlogEntry.setId(request.getComment().getBlogEntryId().getValue());
blogEntryFacade.create(persistBlogEntry);
} else {
persistBlogEntry = blogEntries.get(0);
}
Comment persistComment = new Comment();
persistComment.setId(request.getComment().getID().getValue());
persistComment.setBody(request.getComment().getBody().getValue());
/*
set other properties
*/
persistComment.setBlogEntry(persistBlogEntry);
commentFacade.create(persistComment);
...
这是实现的代码片段CreateBlogEntry
:
@EJB
private BlogEntryFacade blogEntryFacade;
...
List<BlogEntry> blogEntries = blogEntryFacade.findById(request.getBlogEntry().getId().getValue());
BlogEntry persistBlogEntry;
Boolean update = false;
if (blogEntries.isEmpty()) {
persistBlogEntry = new BlogEntry();
} else {
persistBlogEntry = blogEntries.get(0);
update = true;
}
persistBlogEntry.setId(request.getBlogEntry().getId().getValue());
persistBlogEntry.setBody(request.getBlogEntry().getBody().getValue());
/*
set other properties
*/
if (update) {
blogEntryFacade.edit(persistBlogEntry);
} else {
blogEntryFacade.create(persistBlogEntry);
}
...
这是一些无法使事情按预期发生的摆弄。
遗憾的是,我还没有找到同步这些同时服务调用的方法。我可以让CreateCommentForUpcomingBlogEntry
睡眠几秒钟,但我认为这不是正确的方法。
我可以强制我facades
和他们各自的每个实例EntityManagers
重新加载他们的数据集吗?我可以将我的请求放在某种队列中,该队列根据某些条件被清空吗?
那么:让它等待BlogEntry
存在的最佳做法是什么?
在此先感谢,大卫
信息:
- GlassFish 服务器 3.1.2
- EclipseLink,版本:Eclipse Persistence Services - 2.3.2.v20111125-r10461