Jarrod Roberson Jarrod Roberson - 8 months ago 41
Java Question

How to automatically register @Entity decorated classes at application start up?

How you do enable Objectify to automatically discover your annotated
classes at runtime?

I want to register my classes at application start up and not have to hard code them into a class as recommended in the documentation.



This is no runtime reflection cost solution:

import com.google.appengine.api.ThreadManager;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.annotation.Entity;
import org.reflections.Reflections;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

 * This class processes the classpath for classes with the @Entity or @Subclass annotations from Objectify
 * and registers them with the ObjectifyFactory, it is multi-threaded and works very fast!
public class ObjectifyLoaderContextListener implements ServletContextListener
    private static final Logger L = LoggerFactory.getLogger(ObjectifyLoaderContextListener.class);

    private final Set<Class<?>> entities;

    public ObjectifyLoaderContextListener()
        this.entities = new HashSet<>();

    public void contextInitialized(@Nonnull final ServletContextEvent sce)
        final ConfigurationBuilder cb = new ConfigurationBuilder();
        final ExecutorService es = Executors.newCachedThreadPool(ThreadManager.currentRequestThreadFactory());
        final Reflections r = new Reflections(cb);
        final ObjectifyFactory of = ObjectifyService.factory();
        for (final Class<?> cls : this.entities)
            L.debug("Registered {} with Objectify", cls.getName());

    public void contextDestroyed(@Nonnull final ServletContextEvent sce)
        /* this is intentionally empty */

Updates to this class will be available in this gist.