我正在处理一个使用Angular + Java + Spring Boot + MongoDB的小应用程序。最近有很多活动(也就是代码修改),但据我所知,数据访问类似乎一直没有受到影响。
然而,似乎MongoRepository
突然决定停止对我保存到数据库中的更改进行持久化。
检查mongod.log
,当save()
成功时,下面是所见到的内容:
2018-04-11T15:04:06.840+0200 I COMMAND [conn6] command pdfviewer.bookData command: find { find: "bookData", filter: { _id: "ID_1" }, limit: 1, singleBatch: true } planSummary: IDHACK keysExamined:1 docsExamined:1 idhack:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:1 nreturned:1 reslen:716 locks:{ Global: { acquireCount: { r: 4 } }, Database: { acquireCount: { r: 2 } }, Collection: { acquireCount: { r: 2 } } } protocol:op_query 102ms
2018-04-11T17:30:19.615+0200 I WRITE [conn7] update pdfviewer.bookData query: { _id: "ID_1" } update: { _class: "model.BookData", _id: "ID_1", config: { mode: "normal", offlineEnabled: true }, metadata: { title: "PDFdePrueba3pag copia 6 ", ...}, downloaded: false, currentPageNumber: 2, availablePages: 3, bookmarks: [], stats: { _id: "c919e517-3c68-462c-8396-d4ba391762e6", dateOpen: new Date(1523460575872), dateClose: new Date(1523460575951), timeZone: "+2", ... }, ... } keysExamined:1 docsExamined:1 nMatched:1 nModified:1 keyUpdates:0 writeConflicts:1 numYields:1 locks:{ Global: { acquireCount: { r: 2, w: 2 } }, Database: { acquireCount: { w: 2 } }, Collection: { acquireCount: { w: 2 } } } 315ms
2018-04-11T17:30:19.615+0200 I COMMAND [conn7] command pdfviewer.$cmd command: update { update: "bookData", ordered: false, updates: [ { q: { _id: "ID_1" }, u: { _class: "model.BookData", _id: "ID_1", config: { mode: "normal", offlineEnabled: true }, metadata: { title: "PDFdePrueba3pag copia 6 ", ...}, downloaded: false, currentPageNumber: 2, availablePages: 3, bookmarks: [], stats: { _id: "c919e517-3c68-462c-8396-d4ba391762e6", dateOpen: new Date(1523460575872), dateClose: new Date(1523460575951), timeZone: "+2", ... }, ... }, upsert: true } ] } keyUpdates:0 writeConflicts:0 numYields:0 reslen:55 locks:{ Global: { acquireCount: { r: 2, w: 2 } }, Database: { acquireCount: { w: 2 } }, Collection: { acquireCount: { w: 2 } } } protocol:op_query 316ms
当它不起作用时,我看到的是这样的:
2018-04-11T18:13:21.864+0200 I NETWORK [initandlisten] connection accepted from 127.0.0.1:64271 #1 (1 connection now open)
2018-04-11T18:18:51.425+0200 I NETWORK [initandlisten] connection accepted from 127.0.0.1:64329 #2 (2 connections now open)
2018-04-11T18:19:06.967+0200 I NETWORK [initandlisten] connection accepted from 127.0.0.1:64346 #3 (3 connections now open)
调试时,在日志文件上执行 tail -f
1,当我的代码调用 findById()
或 save()
时,我看到这些连接出现,所以应用程序似乎可以访问数据库。
以下是相关的 Java 代码(或者说更多相关的 Java 代码):
/* BookData.java */
@Document
public class BookData {
@Id private String id;
// Some more non-Id Strings...
private Config config;
private Metadata metadata;
private Boolean downloaded;
private Integer currentPageNumber;
private int availablePages;
private List<Bookmark> bookmarks;
private StatsModel stats;
@Transient private byte[] contents;
public BookData() {}
// getters and setters
}
/* BookDataRepository.java */
// MongoRepository comes from spring-boot-starter-parent-1.4.5.RELEASE
public interface BookDataRepository extends MongoRepository<BookData, String> {
BookData findById(String id);
}
/* BookDataServiceImpl.java */
public BookData updateBookData(String id, BookData newData) {
final BookData original = bookDataRepository.findById(id);
if (original == null) {
return null;
}
original.setCurrentPageNumber(Optional.ofNullable(newData.getCurrentPageNumber()).orElseGet(original::getCurrentPageNumber));
// similar code for a couple other fields
return bookDataRepository.save(original);
}
我已经在调试过程中仔细检查了一百遍,似乎一切都没问题:
findById(id)
正确返回期望的BookData original
对象:检查 ✓newData
包含用于更新的期望值:检查 ✓- 在调用
save(original)
之前,original
已使用newData
值正确修改:检查 ✓ save()
执行没有错误:检查 ✓save()
返回一个具有正确更新值的新的BookData
:出乎意料地,检查 ✓save()
返回后,在 Mongo Shell 中进行的db.bookData.find()
查询显示值已更新:失败。save()
返回后,通过新的调用findById()
检索到的BookData
对象包含更新的值:失败(有时是这样,有时不是)。
看起来 MongoDB 只是在等待某种形式的flush()
,但这不是可以调用 saveAndFlush()
的 JPA 存储库。
有什么想法为什么会发生这种情况吗?
编辑:版本(按要求):
- Java 8
- Spring Boot 1.4.5
- MongoDB 3.2.6
- Windows 10
我还在上面包含了 BookData
。
verbosity
级别(请参见我的答案),这就是我发现了两个更新的原因。如果我已经怀疑“Java 端有两个更新而不是一个”是根本原因,那么我可能会像你说的那样去做,实际上问题也会浮出水面,因为我会看到来自不同端点的两个save
调用。事后诸葛亮。 - walen