我有一个实体,其中一个字段包含Refs到其他实体的列表(总是4)。我正在尝试获取一些实体,并将它们分配给jsp进行显示。我希望加载字段中的所有Refs,并在jsp中访问它们。
这是我的基本结构:
@Entity
public class Question {
@Id Long id;
@Index String question;
@Load List<Ref<Answer>> answers = new ArrayList<Ref<Answer>>();
}
当我提取这样的问题时,显然jsp中存在错误。有道理,因为答案字段不是答案列表,而是refs:
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());
}
那么如何在jsp中访问答案呢?是手动循环问题并为答案字段执行get()的唯一方法吗?
答案 0 :(得分:8)
您可能会发现这个方便:
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);
}
}
使用此方法,您可以提供以下方法:
@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); }
}
有一点需要注意,它是一个只读列表。通过一点创造力,您可以创建可写的列表,但它需要创建一个ReversibleFunction和一个新的List.transform()方法。如果你只想要一些简单的JSP,你可能不想担心它。
或者,您可以在大多数表达语言中使用Ref的'value'属性。
答案 1 :(得分:7)
这样的事情怎么样:
@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());
}
}
由于您已经使用@Load注释加载了实体,我认为客观化只会将它们从会话缓存中拉出来(它们不会被加载2次)。
如果您没有使用@Load注释,那么此方法将执行批量加载,这可能比循环遍历Refs并单独调用get()更好。
答案 2 :(得分:-1)
如果更改列表类型会怎样?
@Entity
public class Question {
@Id Long id;
@Index String question;
@Load List<Answer> answers = new ArrayList<Answer>();
}
我检查一下,一切顺利,但在文档(https://code.google.com/p/objectify-appengine/wiki/Entities#Ref _ s)中没有任何对此案例的引用。
这样做是否安全?