Unable to display data from relationships in templates

43 views Asked by At

I'm stuck with trying to display data for a One-to-One relationship in Twirl templates (using Play Framework Java - 2.5.10). Basically I have a User model:

package models;

import java.sql.Date;
import javax.persistence.*;
import com.avaje.ebean.Model;

@Entity
@Table(name = "users")
public class User extends Model {
    @Id
    @Column(name = "id")
    public Long id;

    @Column(name = "first_name")
    public String firstName;

    @Column(name = "middle_name")
    public String middleName;

    @Column(name = "last_name")
    public String lastName;

    @Column(name = "date_of_birth")
    public Date dateOfBirth;

    @Column(name = "sex")
    public String sex;

    @OneToOne
    @JoinColumn(name = "time_zone_id")
    public TimeZone timeZone;

    public static Finder<Long, User> find = new Finder<>(User.class);
}

and the Farmer model:

package models;

import com.avaje.ebean.Model;

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

@Entity
@Table(name="farmers")
public class Farmer extends Model {
    public enum Status {INACTIVE, ACTIVE}

    @Id
    @Column(name="id")
    public Long id;

    @OneToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name="user_id")
    public User user;

    @Column(name="profile_pic_url")
    public String profilePicUrl;

    @Column(name="access_url")
    public String accessUrl;

    @Column(name="status")
    public String status = Status.INACTIVE.name();

    @OneToMany(mappedBy = "farmer", targetEntity = Farm.class, fetch = FetchType.LAZY)
    public List<Farm> farms;

    public static Finder<Long, Farmer> find = new Finder<>(Farmer.class);

    public static List<Farmer> getAllActive() {
        return Farmer.find.where().eq("status", Status.ACTIVE.name()).findList();
    }
}

Notice there's a one-to-one with User model with fetch type set to eager. Now, I want to display data of farmers in my template, where a farmer's name is actually the name in the associated User model.

So I did this in my controller:

public class FarmerController extends Controller {
    public Result all() {
        return ok(farmers.render(Farmer.getAllActive()));
    }
    public Result farmer(Long id, String url) {
        return ok(farmer.render());
    }
}

Now this gets me the right farmer data, but when I try to display the name via the User model, I get null. More specifically, writing this results in nulls (I get nullnull, actually):

<div><h4>@(farmer.user.firstName + farmer.user.lastName)</h4></div>

What am I missing?

1

There are 1 answers

0
marcospereira On BEST ANSWER

As discussed at the comments, this is because play-enhancer does not works for views or any Scala code at all. Since Twirl compiles scala.html code to scala code, this compiled code is not touched by the enhancer.

The solution is then to manually create the get for the relationship:

public class Farmer extends Model {

    public User getUser() {
        return this.user;
    }

}

This is Java code and then will be handled as expected. Of course, you have to change your views to use farmer.getUser instead of farm.user.


Also, as stated at the docs, byte code enhancement involves some magic. But you can avoid it at all and just use regular POJOs (with explicitly declared gets and sets).