Routing to default EDIT template with composite key in crud Play 1.2.4
Asked Answered
S

1

7

I have a composite key of User Id and User Role in my DB.

For mapping the DB with the model, below is the code:

    @Id
@Column(name="ID")
public int userId;
@Id
    @Column(name="USER_ROLE")
public String userRole;
......
    ......
    @Override
public String toString() {      
    return userId;
}

Presently I am able to display the list of users and also able to add new user for my application. But When I try to route to the default "Edit" template by clicking a User Id then I receive an error: "No Route".

Also, I can see that on click of an user, the composite id is not getting send as the URL, in fact some object is being appended at the end of the url (which might be a reason for this).

Kindly let me know how to display the default edit screen when we have a composite key in the DB. I have been struggling with this issue since quite some time but did not got any reference materials in documentation :(

Syrupy answered 12/6, 2013 at 6:22 Comment(2)
The object that is being appended to the end of the URL as mentioned by the OP would apparently be generated by the default toString method. I presume this needs to be overridden; however I don't know how to do so such that the correct underlying model will be edited.Coonan
Can you show the code you're using to generate the URL?Bonanza
B
2

The Play CRUD controller doesn't work well with composite keys. Here's how you can work around it.

First, decide on a stringified format for your composite keys - in the example below I've just taken the two keys (ssn, accountId) and concatenated them separated with a "-".

In your model override the _key and findById methods from GenericModel and JPABase as follows:

package models;

import play.db.jpa.GenericModel;

import javax.persistence.Entity;
import javax.persistence.Id;    

@Entity
public class Part extends GenericModel {
    @Id
    public int ssn;
    @Id
    public int accountId;
    public String name;

    /**
     * Find a part by its composite id ("ssn-accountId")
     */
    public static Part findById(String id) {
        // Split the composite id to extract ssn and accountId
        String[] elements = id.split("-");
        int ssn = Integer.valueOf(elements[0]);
        int accountId = Integer.valueOf(elements[1]);

        return Part.find("ssn=? AND accountId=?", ssn, accountId).first();
    }

    /**
     * Return a composite id ("ssn-accountId")
     */
    public String _key() {
        return ssn + "-" + accountId;
    }
}

Next override the show method in your controller:

    package controllers;

    import models.Part;

    public class Parts 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);
        Part object = Part.findById(id);
        notFoundIfNull(object);
        render("CRUD/show.html", type, object);
    }
}

That's it.

Bissextile answered 9/10, 2013 at 17:16 Comment(2)
@DidarBurmaganov, You might be kidding!Ski
CRUD doesn't support editing simple primary keys so I'm going to guess bad things will happen if you try to edit a composite key. If at all possible you should avoid composite keys - introduce a surrogate / technical key. If you need ssn-accountId to be unique then also add a constraint.Bissextile

© 2022 - 2024 — McMap. All rights reserved.