Search code examples
playframework-2.0playorm

What is the purpose of setting up a class list property at the time of startup?


What is the purpose of setting up a class list property at the time of startup? Looking at code it seems that it is used to check if a re-scan is required or not. What is the reason?

If this list is mandatory, which it looks like because we are doing an unchecked list.get(0) almost everywhere, why not just have a mandatory check at the startup. Maybe when I understand what the list is being used for I would be able to actually put some values.


Solution

  • You should not need to use rescan ever. This is mainly for frameworks like playframework. In playframework, the reason, you never restart the server is that it recompiles your classes and puts them in a "new" classloader meaning your controllers will have trouble if these newly reloaded classes are not "rescanned". This rescan method is for development mode only in playframework. Actually, rescan should probably not be in api but be moved into impl. Right now it is used by the NoSql which is used in playframework to get the EntityManager as is NoSql.em();

    The following code in NoSql.java is what uses the rescan(NOTE: the test of if newClass == testClass is testing is some entity Car.class == Car.class and if the two Car.class are not equal, we know that playframework reloaded it's classes and we need to rescan those new ones)....they do the same thing for hibernate as they have to rescan hibernate entities too.

    @SuppressWarnings("rawtypes")
    private static void testForRescan() {
        List<Class> classesToScan = playCallback.getClassesToScan();
        Class newClass = classesToScan.get(0);
        if(newClass == testClass)
            return;
    
        //otherwise, we need a rescan of all the new classes
        ClassLoader cl = playCallback.getClassLoader();
        factory.rescan(classesToScan, cl);
        testClass = newClass;
    }
    

    Until we develop the playframework plugin, you need to implement the PlayCallback interface (which should be renamed to WebFrameworkCallback) like so if you are using playframework

    private static class OurPlayCallback implements PlayCallback {
        @Override
        public List<Class> getClassesToScan() {
            return Play.classloader.getAnnotatedClasses(NoSqlEntity.class);
        }
    
        @Override
        public ClassLoader getClassLoader() {
            return Play.classloader;
        }
    
        @Override
        public Object getCurrentRequest() {
            return Http.Request.current.get();
        }
    }
    

    so basically, until we do a playframework plugin, on startup, you can initialize the playOrm with the above implementation and then call this to initalize the NoSql.java class(only call this once on startup!!!!)

     NoSql.initialize(new OurPlayCallback(), db, builder);