Manera correcta de obtener el objeto Realm por su clave principal en Android Java

Me pregunto si hay una manera correcta de recuperar un objeto dado su clave primaria en Realm para Android. Sé que el método objectForPrimaryKey existe en Swift, pero parece que no hay tal contrapartida en Realm para Android. Realmente creo que haciendo realm.where(EventInfo.class).equalTo("id", eventInfo.id).findFirst(); parece un montón de residuos (al menos no es muñeca-friendly). ¿Me falta algún método? Actualmente estoy utilizando Realm 1.0.1

Esta es la razón por la que tengo un repositorio Realm como éste (el cual escribí)

 public class CalendarEventRepositoryImpl extends LongRealmRepositoryImpl<CalendarEvent> implements CalendarEventRepository { public CalendarEventRepositoryImpl() { super(CalendarEvent.class); } @Override public Long getId(CalendarEvent calendarEvent) { return calendarEvent.getId(); } public void setId(CalendarEvent calendarEvent, Long id) { calendarEvent.setId(id); } public String getIdFieldName() { return CalendarEventFields.ID; } } 

y findOne(realm, id); un método llamado findOne(realm, id); me gusta

 CalendarEvent event = calendarEventRepository.findOne(realm, id); 

Pero sí, por defecto, es realm.where(CalendarEvent.class).equalTo("id", id).findFirst();

¿Me falta algún método?

Nope. Como mencionó beeender, no está implementado actualmente. El progreso / discusión puede ser rastreado aquí .

Una función auxiliar podría verse así

 public class Cat extends RealmObject { @PrimaryKey private int id; private String name; public Cat getByPrimaryKey(Realm realm, int id) { return realm.where(getClass()).equalTo("id", id).findFirst(); } } 

Es un método específico de clase porque cada clase puede tener un tipo de clave primaria diferente. Tienes que pasar una instancia de dominio a la que administras en la clase de llamada.

He terminado creando una clase de ayuda para esto. Lo usaré hasta que el equipo Realm implemente estos métodos. He llamado a la clase Find (puede cambiar el nombre de la manera que desee, ya que nombrar las cosas y la invalidación de caché son las cosas más difíciles en la informática ). Creo que es mejor usar esto que llamar a where().equalTo() pasando el nombre de la clave primaria como un valor de cadena. De esta manera, seguro que utilizará el campo de clave principal correcto. Aquí está el código:

 import java.util.Hashtable; import io.realm.Realm; import io.realm.RealmModel; import io.realm.RealmObjectSchema; public final class Find { // shared cache for primary keys private static Hashtable<Class<? extends RealmModel>, String> primaryKeyMap = new Hashtable<>(); private static String getPrimaryKeyName(Realm realm, Class<? extends RealmModel> clazz) { String primaryKey = primaryKeyMap.get(clazz); if (primaryKey != null) return primaryKey; RealmObjectSchema schema = realm.getSchema().get(clazz.getSimpleName()); if (!schema.hasPrimaryKey()) return null; primaryKey = schema.getPrimaryKey(); primaryKeyMap.put(clazz, primaryKey); return primaryKey; } private static <E extends RealmModel, TKey> E findByKey(Realm realm, Class<E> clazz, TKey key) { String primaryKey = getPrimaryKeyName(realm, clazz); if (primaryKey == null) return null; if (key instanceof String) return realm.where(clazz).equalTo(primaryKey, (String)key).findFirst(); else return realm.where(clazz).equalTo(primaryKey, (Long)key).findFirst(); } public static <E extends RealmModel> E byKey(Realm realm, Class<E> clazz, String key) { return findByKey(realm, clazz, key); } public static <E extends RealmModel> E byKey(Realm realm, Class<E> clazz, Long key) { return findByKey(realm, clazz, key); } } 

El uso es sencillo:

 // now you can write this EventInfo eventInfo = Find.byKey(realm, EventInfo.class, eventInfoId); // instead of this EventInfo eventInfo = realm.where(EventInfo.class).equalTo("id", eventInfo.id).findFirst(); 

Volverá null si no hay una clave primaria para el objeto dado o si el objeto no se encuentra. Consideré lanzar una excepción si no había clave primaria, pero decidí que era exagerado.

Yo estaba realmente triste genéricos Java no son tan poderosos como genéricos C #, porque realmente, realmente me encantaría llamar al método de la siguiente manera:

 Find.byKey<EventInfo>(realm, eventInfoId); 

Y créanme lo intenté! He buscado por todas partes cómo obtener el valor genérico de un método de retorno de método. Cuando resultó imposible, ya que Java borra los métodos genéricos, intenté crear una clase genérica y usar:

 (Class<T>)(ParameterizedType)getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; 

Y todas las permutaciones posibles en vano! Así que me di por vencido …

Nota: Sólo implementé las versiones Cadena y Larga de Find.byKey porque Realm acepta sólo los datos String y Integral como claves primarias, y Long permitirá la consulta de campos Byte y Integer también (¡espero!).

Con el nuevo Realm puedes acceder a la clave primaria de tu tabla usando el esquema de tu DB de esta manera:

 private String load(Class realmClass) { return mRealm.getSchema().get(realmClass.getSimpleName()).getPrimaryKey(); } 

No soy muy experto en anotación, he intentado leer el valor de @PrimaryKey en tiempo de ejecución por reflexión, usando getAnnotation() en los campos, pero los valores siempre son null , tal vez debido a @Retention(RetentionPolicy.CLASS) .

  • No se puede agregar un nuevo objeto a RealmList debido a la referencia de objeto null
  • Android: Realm + Retrofit - Serializar apiresponse
  • Limitar el número de llamadas al usar Parse
  • Cambiar el tipo de datos del campo Realm - Java
  • ¿Cuál es la forma correcta de tratar con multithreading y Realm?
  • Cómo usar Realm's en el método con Kotlin
  • Acceso de dominio a través de subprocesos con rxjava y dagger2
  • Realm creado con Android en un proyecto no es válido en Otro
  • Android: Realm + Retrofit 2 + Gson
  • ¿Cómo encubierta realmResult a la matriz y pasar a otra actividad?
  • ¿Cómo sincronizar los datos del servidor en la aplicación android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.