So this might be kind of a dumb question but when do you register classes with:
ObjectifyService.register( User.class );
Currently, I\'m doing
I use the @Entity annotation, the Reflections library and runtime registration with no significant impact in start up time of any of my applications because all the information is collected at compile/build time.
package com.vertigrated.servlet;
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 uses a prebuilt list of classes to process
* created by the Reflections library at compile time 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<>();
}
@Override
public void contextInitialized(@Nonnull final ServletContextEvent sce)
{
final ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setUrls(ClasspathHelper.forPackage(""));
final ExecutorService es = Executors.newCachedThreadPool(ThreadManager.currentRequestThreadFactory());
cb.setExecutorService(es);
final Reflections r = new Reflections(cb);
this.entities.addAll(r.getTypesAnnotatedWith(Entity.class));
es.shutdown();
final ObjectifyFactory of = ObjectifyService.factory();
for (final Class<?> cls : this.entities)
{
of.register(cls);
L.debug("Registered {} with Objectify", cls.getName());
}
}
@Override
public void contextDestroyed(@Nonnull final ServletContextEvent sce)
{
/* this is intentionally empty */
}
}
Based on Danie's answer and in case someone else is using dependency injection I did this for Spring MVC and worked perfect:
I created a service as follows:
@Service
@Qualifier("objectifyService")
public class OfyService {
static {
ObjectifyService.register(GaeUser.class);
}
public static Objectify ofy() {
return ObjectifyService.ofy();
}
public static ObjectifyFactory factory() {
return ObjectifyService.factory();
}
}
Then whenever I want to use it I just inject the service like this:
@Autowired
@Qualifier("objectifyService")
OfyService objectifyService;
And then I use it like this:
objectifyService.ofy().save().entity(user).now();
Update
Here is the Best Practice Solution:
Use Your Own Service , This guarantees that your entities are registered before you use Objectify, but doesn't necessarily impact application startup for requests which do not access the datastore.
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;
public class OfyService {
static {
ObjectifyService.register(User.class);
}
public static Objectify ofy() {
return ObjectifyService.begin();//prior to v.4.0 use .begin() ,
//since v.4.0 use ObjectifyService.ofy();
}
public static ObjectifyFactory factory() {
return ObjectifyService.factory();
}
}
Then use it like this:
public User createUser(User pUser) {
Objectify objectify = OfyService.ofy();
objectify.put(pUser);
return pUser;
}
Original Answer (better use the code above):
you should do it this way in your class, just put a static block like this:
static{
ObjectifyService.register( User.class );
}
p.s , you take a look at the best practice of objectify too
http://code.google.com/p/objectify-appengine/wiki/BestPractices