UPDATE 2: I think I've made some progress. My IDE is much happier about my code, but I just have one final line that is upset:
CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
fromProviders(PojoCodecProvider.builder().automatic(true).build()));
MongoClientURI connectionString = new MongoClientURI("my-mongo-string");
MongoClient mongoClient = new MongoClient(connectionString);
MongoDatabase database = mongoClient.getDatabase("New");
database = database.withCodecRegistry(pojoCodecRegistry);
MongoCollection<? extends Person> collection = database.getCollection("people", this.getClass());
collection = collection.withCodecRegistry(pojoCodecRegistry);
collection.insertOne(this);
I've swapped the name of my 'Collection' over to 'Person' to temporarily prevent colllisisons with Java's 'Collection'. Everything seems good except that last line, which gives me this error: insertOne (capture<? extends Utils.Person>) in MongoCollection cannot be applied to (Utils.Person). The 'this' is referring to my person class. What am I doing wrong here?
UPDATE: Original Question below. I believe I have now determined that generics are my best bet. However I am having some issues 'generifying' these two lines (assuming I've initialized database correctly):
MongoCollection<MyClass> collection = database.getCollection("SomeString", MyClass.class);
What is the best way to do this? Java doesn't seem to like using .class on a generic.
Original Question:
So I want to take advantage of the MongoDB drivers ability to store PJOS. Example Here. But I plan on having multiple classes stored to the database, and I don't want to have to retype all of the connection code every time, nor do I want to copy and paste and then minorly modify the code for each class. I had the idea to make a "Collection" class, and then extend that, but it's not quite working how I intended. Here is my code:
public class Collection {
private MongoCollection<Collection> collection;
public Collection(){}
public Collection(String databaseName){
databaseName = databaseName.toLowerCase().replaceAll(" ", "");
CodecRegistry pojoCodecRegistry = fromRegistries(com.mongodb.MongoClient.getDefaultCodecRegistry(),
fromProviders(PojoCodecProvider.builder().automatic(true).build()));
MongoClientURI connectionString = new MongoClientURI("my-mongo-connection-string");
com.mongodb.MongoClient mongoClient = new com.mongodb.MongoClient(connectionString);
MongoDatabase database = mongoClient.getDatabase(databaseName);
database = database.withCodecRegistry(pojoCodecRegistry);
collection = database.getCollection(this.getClass().getName(), Collection.class);
}
public Collection findOne(Document document){
return collection.find(document).first();
}
public void save(){
collection.insertOne(this);
}
}
As you can see, I want to be able to pass in the database name to any class that inherits from this class (Or whatever the right thing to do is.), and have my code connect to the database and find or save a POJO of the respective sub-class properly. So for example, if I had a Person class with a phone number, I could just extend my Collections class and count on everything to work. Right now, when I call the save function on a child class, it tries to save the parent Collection, and I get an error Can't find a codec for class Utils.MongoDb.Collection. (My Collection class is in my own Utils.MongoDb namespace). Am I just missing something? Is there a better way to go about this? The only way I can think to get this to work is copy and paste the code in my Collection constructor into each class, and modify it with the right class variables. I hope all of this is clear. Thanks in advance!