query español java google-app-engine objectify

java - query - objectify en español



¿Cuándo se registran las clases en Objectify para GAE? (3)

Basado en la respuesta de Danie y en el caso de que alguien más esté usando la inyección de dependencia, hice esto para Spring MVC y funcionó a la perfección:

He creado un servicio de la siguiente manera:

@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(); } }

Luego, cuando quiera usarlo, simplemente inyecto el servicio de esta manera:

@Autowired @Qualifier("objectifyService") OfyService objectifyService;

Y luego lo uso así:

objectifyService.ofy().save().entity(user).now();

Entonces, esta podría ser una pregunta tonta, pero ¿cuándo registrar clases con:

ObjectifyService.register( User.class );

Actualmente, estoy haciendo esto en el constructor de una clase de interfaz que uso en mis otras clases para simplificar el uso del almacén de datos específicamente para mi aplicación. Sin embargo, estoy recibiendo este error:

Intenté registrar el tipo ''Usuario'' dos veces

Entonces, supongo que mi pregunta es con qué frecuencia y específicamente, ¿cuándo se registran las clases en Objectify?

¡Gracias!

PS Aquí está toda mi clase:

import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Iterator; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.persistence.Id; import com.googlecode.objectify.Objectify; import com.googlecode.objectify.ObjectifyService; import com.googlecode.objectify.annotation.Indexed; import com.googlecode.objectify.annotation.Unindexed; public class UsersService { Objectify ojy; public UsersService(){ ObjectifyService.register( User.class ); ojy = ObjectifyService.begin(); } public void regUser(String email, String password, String firstName, String lastName){ //TODO: Check syntax if email //TODO: store encrypted password } public void regUser(String email, String password, String firstName){ regUser(email, password, firstName, null); } public void regUser(String email, String password){ regUser(email, password, "", ""); } public boolean checkFor(Long acc_id){ User checked_user = ojy.find(User.class, acc_id); if(checked_user == null){ return false; }else{ return true; } } public User getUser(String email, String password) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException{ String pass_enc = MyUtils.getEncrypted(password); Iterable<User> users = ojy.query(User.class).filter("email", email).filter("password", pass_enc); Iterator<User> iter = users.iterator(); if(iter.hasNext()){ return iter.next(); }else{ return null; } } }


Utilizo la anotación @Entity , la biblioteca de Reflections y el registro en tiempo de ejecución sin ningún impacto significativo en el tiempo de inicio de ninguna de mis aplicaciones porque toda la información se recopila en el momento de la compilación / compilación.

ObjectifyLoaderContextListener.java

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 */ } }


Actualizar

Aquí está la solución de la mejor práctica:

Use su propio servicio. Esto garantiza que sus entidades están registradas antes de usar Objectify, pero no necesariamente afecta el inicio de la aplicación para solicitudes que no acceden al almacén de datos.

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(); } }

Entonces úsalo así:

public User createUser(User pUser) { Objectify objectify = OfyService.ofy(); objectify.put(pUser); return pUser; }

Respuesta original (mejor use el código de arriba):

Debería hacerlo de esta manera en su clase, solo coloque un bloque estático como este:

static{ ObjectifyService.register( User.class ); }

ps, usted echa un vistazo a la mejor práctica de objetivar también

http://code.google.com/p/objectify-appengine/wiki/BestPractices