序列化列表与json的manytoone&onetomany关系

我有课程菜单,这是一个自我与自我与多人和onetomany关系。

package models; import java.util.*; import javax.persistence.*; import play.db.ebean.*; import play.data.format.*; import play.data.validation.*; import static play.data.validation.Constraints.*; import javax.validation.*; import org.codehaus.jackson.annotate.JsonBackReference; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.annotate.JsonManagedReference; import com.avaje.ebean.*; import play.i18n.Messages; @Entity public class Menu extends Model { @Id @GeneratedValue(strategy = GenerationType.AUTO) public Long id; @Required @MinLength(4) @MaxLength(30) public String name; public String url; @Transient public boolean hasChild() { return url.isEmpty(); } public Integer idx; @Temporal(TemporalType.TIMESTAMP) @Formats.DateTime(pattern = "yyyy/MM/dd hh:mm:ss") public Date created; @Required public boolean enabled; @ManyToOne @JsonBackReference public Menu parent; @OneToMany @JsonManagedReference("parent") public List children; public static Model.Finder find = new Model.Finder(Long.class, Menu.class); public static List findTops() { return find.where().eq("parent_id", null).eq("enabled", true).orderBy("idx asc").findList(); } public static List findChildsByParent(Menu parent) { return findChildsByParent(parent, true); } public static List findChildsByParent(Menu parent, boolean enabled) { return find.where().eq("parent_id", parent.id).eq("enabled", enabled).orderBy("idx asc").findList(); } public static boolean hasChilds(Menu parent) { return hasChilds(parent, true); } public static boolean hasChilds(Menu parent, boolean enabled) { return find.where().eq("parent_id", parent.id).eq("enabled", enabled).findList().size() > 0; } public static Page findPage(int page, int size) { return find.findPagingList(size).getPage(page - 1); } public Menu() { } } 

在Controller代码中是:

 @BodyParser.Of(BodyParser.Json.class) public static Result menuJson() { if (menus == null) { menus = Menu.find.all(); } JsonNode json = new ObjectMapper().valueToTree(menus); return ok(json); } 

错误详细信息是:

 [RuntimeException: java.lang.IllegalArgumentException: Query threw SQLException:Unknown column 't1.menu_id' in 'on clause' Bind values:[1] Query was: select t0.id c0 , t1.id c1, t1.name c2, t1.url c3, t1.idx c4, t1.created c5, t1.enabled c6, t1.parent_id c7 from menu t0 left outer join menu t1 on t1.menu_id = t0.id where t0.id = ? order by t0.id (through reference chain: com.avaje.ebean.common.BeanList[0]->models.Menu["children"])] 

它有很好的解决方案来解决它们或如何声明自定义序列化? 对于树模型,我没有很好的对象设计,这个环境是不是有更好的设计?

我解决了

在OneToMany上添加映射是有效的。

 package models; import java.util.*; import javax.persistence.*; import play.db.ebean.*; import play.data.format.*; import play.data.validation.*; import static play.data.validation.Constraints.*; import javax.validation.*; import org.codehaus.jackson.annotate.JsonBackReference; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.annotate.JsonManagedReference; import com.avaje.ebean.*; import play.i18n.Messages; @Entity public class Menu extends Model { @Id @GeneratedValue(strategy = GenerationType.AUTO) public Long id; @Required @MinLength(4) @MaxLength(30) public String name; public String url; @Transient public boolean hasChild() { return url.isEmpty(); } public Integer idx; @Temporal(TemporalType.TIMESTAMP) @Formats.DateTime(pattern = "yyyy/MM/dd hh:mm:ss") public Date created; @Required public boolean enabled; @ManyToOne @JsonBackReference public Menu parent; @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST) @JsonManagedReference public List children; public static Model.Finder find = new Model.Finder(Long.class, Menu.class); public static List findTops() { return find.where().eq("parent_id", null).eq("enabled", true).orderBy("idx asc").findList(); } public static List findChildsByParent(Menu parent) { return findChildsByParent(parent, true); } public static List findChildsByParent(Menu parent, boolean enabled) { return find.where().eq("parent_id", parent.id).eq("enabled", enabled).orderBy("idx asc").findList(); } public static boolean hasChilds(Menu parent) { return hasChilds(parent, true); } public static boolean hasChilds(Menu parent, boolean enabled) { return find.where().eq("parent_id", parent.id).eq("enabled", enabled).findList().size() > 0; } public static Page findPage(int page, int size) { return find.findPagingList(size).getPage(page - 1); } public Menu() { } }