playframework-1.x

Why does my nested POJO return null from a form in Play! 1.x


In Play! Framework 1.5.1, why am I getting null back for thingy.Owner ? Shouldn't the automatic binding take care of this?

User class

    package models;

@Entity
@Table(name="objtest_user")
public class User extends Model
{
    @Required
    public String username;

    @Password
    @Required
    public String password;

    public String fullname;

    public User(String username, String password, String fullname)
    {
        this.username = username;
        this.password = password;
        this.fullname = fullname;
    }

    @Override
    public String toString()
    {
        return this.fullname;
    }
}

and this Thingy class that references the User class

    package models;

import java.util.*;
import javax.persistence.*;

import play.db.jpa.*;
import play.data.validation.*;

@Entity
public class Thingy extends Model
{
    @Required
    public String Name;

    @ManyToOne
    public User Owner;

    public Thingy(String name, User owner)
    {
        this.Name = name;
        this.Owner = owner;
    }

    @Override
    public String toString()
    {
        return Name;
    }
}

and this Template form

#{extends 'main.html' /}
#{set title:'Home' /}

<p>Current user = ${currentUser}</p>


#{form @saveThingy(), id:'saveThingy'}
    <input type="text" id="thingy.Name" name="thingy.Name"/>
    <input type="hidden" id="thingy.Owner" name="thingy.Owner" value="${currentUser}"/>
    <input type="submit" id="Save" value="Save"/>
#{/form}

Controller method

public static void saveThingy(Thingy thingy)
{
    System.out.println("Name = " + thingy.Name);
    System.out.println("Owner = " + thingy.Owner);

    thingy.save();
}

Solution

  • Try changing the following line

    <input type="hidden" id="thingy.Owner" name="thingy.Owner" value="${currentUser}"/>
    

    To

    <input type="hidden" id="thingy.Owner" name="thingy.Owner.id" value="${currentUser.id}"/>
    

    If you check out the docs (https://www.playframework.com/documentation/1.2.x/controllers#params), and look for JPA object binding section, it talks about requiring sub objects to have an id. Play when it finds an ID for an object, it will load the relavent entity via JPA/Hibernate.