mosid
mosid

Reputation: 1114

playframework - many to many with extra columns using the crud module

Assuming i have an employeee class and a project class where i want to assign multiple ( multiple select ) employees to a project and having extra column 'notified' in the join table i tried the method showed here, but did not work for me.

here is my classes ( the ones that i am really sure about)

Employee.java

class Employee extends Model{
    //Some properties
  .....
 }

Project.class

 class Project extends Model{
    //Some properties
    ......

    @ManyToMany
    public List<Employee> assignedEmp;
 }

I am using playframework 1.2.5.3 and the crud module.

and does the crud module figure it out of the box?

Really appreciate any help here. i am totally lost.

Upvotes: 0

Views: 283

Answers (1)

Mariusz Nosiński
Mariusz Nosiński

Reputation: 1288

It isn't easy to resolve your problem in play framework but it's possible with some work.
First you should to do is defining JoinModel with additional property you need and with composite ID key build from employee and project ids. CRUD doesn't like composite keys, then you should overwrite _key() and findById() methods of this model. At last you need to overwrite show() method within crud controller for this model.

@Entity
public class Project extends Model {
    public String name;

    @OneToMany(mappedBy = "project")
    public List<ProjectEmployee> projectEmployees = new ArrayList<ProjectEmployee>();

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


@Entity
public class Employee extends Model {
    public String name;

    @OneToMany(mappedBy = "employee")
    public List<ProjectEmployee> projectEmployees = new ArrayList<ProjectEmployee>();

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

@Entity
    @Table(name = "project_employee")
    public class ProjectEmployee extends GenericModel {


    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "project_id", insertable = false, updatable = false)
    public Project project;

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "employee_id", insertable = false, updatable = false)
    public Employee employee;

    public boolean notified = false;

    public String _key() {
        try {
            return project.id + "-" + employee.id;
        } catch (NullPointerException npe) {
            return "0-0";
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("ProjectEmployee[");
        if (project != null) sb.append(project.name).append("-");
        if (employee != null) sb.append(employee.name);
        sb.append("]");
        return sb.toString();
    }

    public static ProjectEmployee findById(String id) {
        String[] elements = id.split("-");
        int projectId = Integer.valueOf(elements[0]);
        int employeeId = Integer.valueOf(elements[1]);

        return ProjectEmployee.find("project_id=? AND employee_id=?", projectId, employeeId).first();
    }
}

and controller:

@CRUD.For(ProjectEmployee.class)
public class ProjectEmployees extends CRUD {

/**
 * CRUD show method doesn't know how to handle composite ids.
 *
 * @param id composite of ssn + "-" + accountId
 * @throws Exception
 */
public static void show(String id) throws Exception {
    // Do not rename 'type' or 'object'
    ObjectType type = ObjectType.get(getControllerClass());
    notFoundIfNull(type);
    ProjectEmployee object = ProjectEmployee.findById(id);
    notFoundIfNull(object);
    render("CRUD/show.html", type, object);
}


}

Working example repository hosted at bitbucket

Upvotes: 2

Related Questions