Objectify - how @Load List <Ref <? >>?

I have an object with a field containing a list for links to other objects (always 4). I am trying to get some entities and send them to jsp for display. I want all Refs fields in the field to be loaded, as well as to access them in jsp.

Here is my basic structure:

@Entity public class Question { @Id Long id; @Index String question; @Load List<Ref<Answer>> answers = new ArrayList<Ref<Answer>>(); } 

When I ask such a question, it is obvious that there is an error in jsp. It makes sense because the answer field is not a list of answers, but a ref:

 ObjectifyService.register(Question.class); ObjectifyService.register(Answer.class); List<Question> questions = ofy().load().type(Question.class).limit(50).list(); req.setAttribute("questions", questions); try { getServletContext().getRequestDispatcher("/admin/view-questions.jsp").forward(req, resp); } catch (ServletException e) { System.out.println (e.getMessage()); } 

So how to access answers in jsp? is this the only way to manually ask questions and do get () for the answer field?

+6
source share
3 answers

You can find it conveniently:

 public class Deref { public static class Func<T> implements Function<Ref<T>, T> { public static Func<Object> INSTANCE = new Func<Object>(); @Override public T apply(Ref<T> ref) { return deref(ref); } } public static <T> T deref(Ref<T> ref) { return ref == null ? null : ref.get(); } @SuppressWarnings({ "unchecked", "rawtypes" }) public static <T> List<T> deref(List<Ref<T>> reflist) { return Lists.transform(reflist, (Func)Func.INSTANCE); } } 

Using this, you can provide a method such as:

 @Entity public class Question { @Id Long id; @Index String question; @Load List<Ref<Answer>> answers = new ArrayList<Ref<Answer>>(); public List<Answer> getAnswers() { return Deref.deref(answers); } } 

One caveat is the read-only list. With a little creativity, you can create a list for writing, but for this you need to create a ReversibleFunction function and a new List.transform () method. If you just need something simple for JSP, you can not worry about it.

Alternatively, you can use the value property to reference Ref in most expression languages.

+9
source

How about something like this:

 @Entity public class Question { @Id Long id; @Index String question; @Load List<Ref<Answer>> answers = new ArrayList<Ref<Answer>>(); public List<Answer> loadAnswers() { return new ArrayList<Answer>(ofy().load().refs(answers).values()); } } 

Since you already loaded the objects using the @Load annotation, I think that objectify will just pull them out of the session cache (they will not be loaded 2x).

And if you do not use the @Load annotation, then this method will do batch loading, which is likely to be better than looping through Refs and call get () links individually.

+4
source

What happens if you change the list type?

 @Entity public class Question { @Id Long id; @Index String question; @Load List<Answer> answers = new ArrayList<Answer>(); } 

I check it and everything is going well, but there is no reference to this case in the documentation ( https://code.google.com/p/objectify-appengine/wiki/Entities#Ref _s).

Is it safe to do this?

-1
source

All Articles