0

I'm designing the architecture for a ODM in Java. I have a hierarchal structure with a top-level abstract Document class. Implementations of DB objects will extend this class.

public abstract class Document {
    ObjectId id;
    String db;
    String collection;
}

public class Student extends Document {
    db = "School";
    collection = "Student";

    String name;
    int age;
    float gpa;
}

I want each class to be able to statically fetch results for its associated collection. For example, I'd like to do something like Students.get(Students.class, new ObjectId(12345)) which would return a Student from the database. Note that I need to specify the class in the get() method, this is a restriction of the object mapper library I'm using (Morphia).

What would be the best way to enforce each class to have this get() method? There are a couple constraints:

  1. get() should be implemented as a static method
  2. I'd like to avoid redundant code if possible and not have to specify the class for each implementation of get(). For example if I have a Student and Teacher class, I want to avoid specifying Students.class and Teacher.class manually. I'm not sure this is possible though, since get() is a static method.

I think this is a variation on the common abstract static Java problem, but I want to make sure I'm approaching it the right way first.

Community
  • 1
  • 1
user2066880
  • 4,825
  • 9
  • 38
  • 64

1 Answers1

1

I assume your student class should look something like this:

@Entity(name="Student")
public class Student extends Document {
    protected String name;
    protected int age;
    protected float gpa;
    ...
}

Generic queries would something like this:

public <E extends BaseEntity> E get(Class<E> clazz, final ObjectId id) {
    return mongoDatastore.find(clazz).field("id").equal(id).get();
}

Why would you want to make this static? You'd hard-code dependencies and break polymorphism; making it impossible to use a mock implementation for tests (which doesn't need a real database).

xeraa
  • 10,456
  • 3
  • 33
  • 66
  • I think the only reason I wanted it static is because it shouldn't be associated with any particular instance of the class. Could you also explain what you mentioned about hard-coding dependencies and breaking polymorphism? I'm having difficulty understanding this in my context. Thanks, really appreciate your input. – user2066880 Jan 19 '15 at 18:36
  • 1
    For a short answer take a look at http://stackoverflow.com/a/17997568/573153 For a long, but really detailed answer see http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/ – xeraa Jan 19 '15 at 21:33
  • 1
    And for a complete code example take a look at https://github.com/xeraa/morphia-demo/blob/master/src/main/java/net/xeraa/morphia_demo/persistence/MongodbGenericPersistence.java – xeraa Jan 19 '15 at 21:34