java - Playframework 2 和 Manytoone 表单绑定(bind)

标签 java spring playframework-2.0 many-to-one

我正在遵循 Play 框架示例计算机数据库应用程序中的示例,并具有以下模型

public class Simulation  implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long id;
    @ManyToOne
    @JoinColumn(name="projection_set_id")
    public ProjectionSet projectionSet;
}

public class ProjectionSet  {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long id;
}

在表单中,我有以下表单助手

@helper.select(
          simulationForm("projectionSet.id"),
          options(ProjectionSet.options),
          '_label -> "Team Context",
          '_showConstraints -> false
)

选项定义为

public static Map<String,String> options() {
    List<ProjectionSet> projectionSets = ProjectionSet.findAll();
    LinkedHashMap<String,String> options = new LinkedHashMap<String,String>();
    for(ProjectionSet set: projectionSets) {
        options.put(set.id.toString(), set.forDate.toString());
    }
    return options;
}

在 Controller 中我有以下内容:

    Form<Simulation> filledForm = simulationForm.bindFromRequest();
    Logger.debug("form = " + filledForm.toString());
    if(filledForm.hasErrors()) {
        final User user = BaseController.currentUser();
        return badRequest(newSimulation.render(user, filledForm));
    } else {
        Map<String, String> formData = filledForm.data();
        Simulation created = filledForm.get();
        created.create();
        return redirect("/simulations");
    }

我遇到的异常(exception)是

Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved  transient instance - save the transient instance before flushing:   models.simulations.Simulation.projectionSet -> models.baseball.ProjectionSet
    at org.hibernate.engine.spi.CascadingAction$8.noCascade(CascadingAction.java:380) ~       [hibernate-core-4.2.7.Final.jar:4.2.7.Final]
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:176) ~[hibernate-core-4.2.7.Final.jar:4.2.7.Final]
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:162) ~[hibernate-core-4.2.7.Final.jar:4.2.7.Final]
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:153) ~[hibernate-core-4.2.7.Final.jar:4.2.7.Final]
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:89) ~[hibernate-core-4.2.7.Final.jar:4.2.7.Final]

放置断点后,出现的问题是我从bindToRequest 获得的Simulation 类有一个ProjectionSet 对象,但其中的所有值均为空。然后我逐步执行了bindToRequest方法,我发现对于嵌套绑定(bind),即projectionSet.id,spring Binder 在setPropertyValue方法中的org.springframework.beans.BeanWrapperImpl类中抛出异常

private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {

特别是,当 PropertyValue 的resolvedDescriptor 为 null 时,它会抛出 NotWriteablePropertyException。

我对 Spring 及其绑定(bind)库非常陌生。我不确定我能做些什么来让这个属性得到正确的解决。有什么想法吗?

最佳答案

尝试为 ProjectionSet 类注册格式化程序。这样 Form.bindFromRequest() 知道如何将提交表单中的 id 转换为实际对象。我更喜欢在应用程序级别定义格式化程序,因此我将它们放在 Global 中对象。

public class Global extends GlobalSettings {
  static {
   play.data.format.Formatters.register(ProjectionSet.class,
                                new Formatters.SimpleFormatter<ProjectionSet>() {
        @Override
        public ProjectionSet parse(String id, Locale locale) throws ParseException {
            ProjectionSet pSet = null;
            try {
                long tmpId = Long.parseLong(id);
                pSet = ProjectionSet.finder.byId(tmpId);
            } catch (NumberFormatException ignored) {
                //unexpected id
            }
            return pSet;
        }

        @Override
        public String print(ProjectionSet pSet , Locale locale) {
            return pSet.id + "";
        }
    });
  }
}

查看this page有关表单处理的更多信息,尤其是定义自定义对象的映射的最后一部分。

关于java - Playframework 2 和 Manytoone 表单绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26129994/

相关文章:

java - 在 Play+Java 中迭代 cookie

java - 通过填充 html 页面字段在运行时创建 apk 文件

java - 使用executeQuery时出现NullPointerException

scala - SBT/Play2 多项目设置不包括运行/测试中类路径中的依赖项目

spring - 如何通过使用异常处理程序注释将错误内容写入响应主体来处理 HttpMediaTypeNotAcceptableException?

javascript - Thymeleaf - 在 Javascript 代码中迭代模型属性

scala - Playframework 2.0 在 View 模板中定义函数

java - 使用 Gson 将 json 放入列表中

java - 代号一 - 存储敏感数据

java - 请解释 RestTemplate