I’m attempting to build my own application and backend API to further my understanding of the Mongo Java driver after completing the M220J course, but am running into a blocker.
Context
I’m creating a bookmark managing app and rebuilding the backend in Java using the Mongo driver and Spring Boot. The error appears when using .iterator()
or .into()
after .find()
to query my Atlas database. The error DOES NOT APPEAR when using .first()
after .find()
.
My pom.xml
includes version 4.2.2 of mongodb-driver-sync. I’m using Java 15.0.1.
The folders collection uses a CodecRegistry, much like how the Users or Sessions collection is created in the mflix app, meaning a query on foldersCollection should return documents of type Folder. I’ve verified that the data has the same fields in the database and Folder.java class.
Code
In the code, the user_id
field is currently stored as a String, not ObjectId, in the Folder documents (acts like a foreign key) This does not cause the error. The .into()
trick was taken from this article talking about Mongo and Java Pojos.
// Returns an array of folders, given a user id
public List<Folder> getFolders(String id) {
if (id == null || id.isEmpty()) return null;
List<Folder> folders = foldersCollection.find(new Document("user_id", id)).into(new ArrayList<>());
return folders;
}
This code also does not work, which uses .iterator()
after .find()
, and excludes the id to get all folders. It also does not work if I include the id in the query.
public List<Folder> getAllFolders(){
List<Folder> folders = new ArrayList<>();
foldersCollection.find().iterator().forEachRemaining(folders::add);
return folders;
}
I have verified that this code works with a test in Java and in Postman:
// Gets a folder from db given folder _id
public Folder getFolder(String id) {
if (id == null || id.isEmpty()) return null;
return foldersCollection.find(new Document("_id", new ObjectId(id))).first();
}
NoSuchMethodError:
It looks like it’s pointing towards the .find()
method when I use .into()
, but I’ve confirmed that .find()
works when chained with .first()
, so I don’t think .find()
is the issue. The same error appears when using .iterator()
.
java.lang.NoSuchMethodError: 'com.mongodb.internal.operation.ExplainableReadOperation com.mongodb.internal.operation.SyncOperations.find(org.bson.conversions.Bson, java.lang.Class, com.mongodb.internal.client.model.FindOptions)'
at com.mongodb.client.internal.FindIterableImpl.asReadOperation(FindIterableImpl.java:236)
at com.mongodb.client.internal.FindIterableImpl.asReadOperation(FindIterableImpl.java:40)
at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:135)
at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:92)
at com.mongodb.client.internal.MongoIterableImpl.forEach(MongoIterableImpl.java:121)
at com.mongodb.client.internal.MongoIterableImpl.into(MongoIterableImpl.java:130)
at com.bookmarkd.api.daos.FolderDao.getFolders(FolderDao.java:46)
at com.bookmarkd.FolderTest.GetFolders(FolderTest.java:50) <31 internal lines>
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) <9 internal lines>
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) <23 internal lines>
Lastly, here’s my Folder class and an image a of a few documents in the Atlas database:
public class Folder {
@BsonId
@JsonIgnore
private ObjectId oid;
@JsonProperty("_id")
@BsonIgnore
private String id;
@JsonProperty("user_id")
private String userId;
private String name;
private String icon;
private boolean shareable;
// Constructor, getters, and setters...
}