playframework,如何创建一个组合框,在其中为我修改JPABean?

playframework,如何创建一个组合框,在其中为我修改JPABean?,playframework,Playframework,我们有: public class TicketDbo { @Required @ManyToOne public ProjectDbo project; } 然后,我们有许多项目可供选择,因此,当您编辑票证时,我们会添加一个下拉菜单,您可以在其中选择一个项目 我们希望呈现类似这样的内容这是最简单的部分,我们知道如何使用{select}完成这部分: 那么我们的控制器将一如既往: public static void postTicket(TicketDbo ticket) {

我们有:

public class TicketDbo {
   @Required
   @ManyToOne
   public ProjectDbo project;
}
然后,我们有许多项目可供选择,因此,当您编辑票证时,我们会添加一个下拉菜单,您可以在其中选择一个项目

我们希望呈现类似这样的内容这是最简单的部分,我们知道如何使用{select}完成这部分:

那么我们的控制器将一如既往:

public static void postTicket(TicketDbo ticket) {
    //at this point the ticket already has the ProjectDbo and validation of it being required has already been run from the @Required annotation
}
有人知道怎么做这样的事吗?或者有没有一个插件可以帮助实现这一点


@第二个问题:如何使用枚举实现这一点?希望这只是对上面的一个调整。

就我所知,做你想做的事情的唯一方法就是使用缓存。创建以下作业:

检索数据库中的项目列表 使用已知键将每个项目存储在缓存中,如ProjectCached_X,其中X是id 作业的运行频率可能与您预期的项目变化频率相同

然后,您可以创建一个方法,用于检查缓存中是否存在ProjectCached\uuSelecteDid并检索它

该系统存在几个问题: -项目可能已出缓存,您需要返回数据库以在该场景中检索它。 -在删除的项目中使用过时数据会有风险,只有在rel失败时,才会在提交中看到这些数据

按Id检索项目应该没什么大不了的,但是。。。您的电话:

点评编辑 很抱歉,您要求在调用控制器之前让一个方法加载对象,这让我感到困惑。如果您需要该方法,那么工作方式是使用缓存


对于控制器方法,您提到您只需要一个参数。事实上,这是你唯一需要的。如果您正确命名select object.field,Play将自动将提供的id与对象链接。或者应该

对于枚举,关联是自动的,只需使用select标记即可

#{select 'object.enumField', items: EnumSet.allOf(enums.MyEnum.class), value: object.enumField /}
如果要显示枚举名称以外的内容,也可以使用“labelProperty”

这样,枚举值将自动与字段关联


我想,对于依赖对象,将select绑定到ticket.project.id是一样的,但我从未尝试过。之后,您可能只需要在控制器中调用merge,但由于Play在绑定时对JPA对象执行了一些特殊操作,因此这可能不起作用。代码保证在调用控制器操作方法之前运行。

从另一个答案上的@maartencls的一个注释来看,这似乎工作得很好

@Global
public class ProjectRefBinder implements TypeBinder<ProjectDBO>{
    @Override
    public Object bind(String name, Annotation[] annotations, String value,
            Class actualClass, Type genericType) throws Exception {
        if(value == null)
            return null;
        EntityManager em = JPA.em();
        Long id = Long.valueOf(value);
        ProjectDBO ref = em.getReference(ProjectDBO.class, id);
        return ref;
    }
}

然后在页面中,我可以做一个{ticket.project}并且在我的控制器方法中,我的TicketDbo最后会有一个ProjectDbo代理,它将所选id包装起来!!!我认为到目前为止效果很好。该类不仅适用于我的TicketDbo,也适用于其他实体中包含ProjectDbo的实体。

当我可以使用entityMgr.getReferenceid时,为什么需要缓存,因此,如果我能获得更多关于如何让playframework实际获取该引用并将所选引用填充到TicketBoie中的详细信息,您可能会有所收获。您的解决方案意味着它违反了我的实际问题,因为方法签名将是postTicketTicketDbo票证,Long selectedId这不是我想要的,因为我最终会有大约6个参数这样做……我只想要传入一个TicketDbo。上的部分可能会有帮助。绑定id是不够的……hibernate需要hibernate通过getReference或find甚至merge创建一个实体,以便将该实体合并回来,然后我才能使用它来保存数据TicketDbo已更改的对象…@maartencis…您可能在那里发现了一些东西!我没有注意到自定义绑定,也许我可以在那里使用JPA.em…我想可能有用。我一直在尝试使用自定义绑定来实现这一点,但没有。显然,JPAPlugin覆盖了这些,并不断抛出错误。。。当您仅仅依赖普通对象/jpa绑定时,Play似乎会加载整个模型。是的,我主要是尝试先解决依赖对象…..然后枚举可能很容易,您的枚举解决方案也很好。这对于仅针对枚举的i18n内容来说效果更好一些。。。{select field.name,items:EnumSet.allOfmodels.EntityStatus.class,value:field.value,valueProperty:'code',labelProperty:'guiLabel'/}相关但不是相同的帖子
#{select 'object.enumField', items: EnumSet.allOf(enums.MyEnum.class), value: object.enumField /}
@Global
public class ProjectRefBinder implements TypeBinder<ProjectDBO>{
    @Override
    public Object bind(String name, Annotation[] annotations, String value,
            Class actualClass, Type genericType) throws Exception {
        if(value == null)
            return null;
        EntityManager em = JPA.em();
        Long id = Long.valueOf(value);
        ProjectDBO ref = em.getReference(ProjectDBO.class, id);
        return ref;
    }
}