manytomany关系无法在play框架中的映射表中保存映射的id

时间:2014-11-15 11:08:56

标签: playframework many-to-many ebean

我正在使用play2.2.1并尝试在 Jobads JobCategory 模型之间创建ManyToMany关系。

我的 Jobads.java

package models;

@Entity
public class Jobads extends Model {

    @Id
    public Long id;

    @ManyToOne
    public Employers employer;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "jobads_jobcategories")
    public List<Jobcategories> jobcategory;

    @ManyToOne
    public Joblocations joblocations;

    @Required
    public String jobtype;

    @Required
    public String title;

    @Required
    public String text;

    @Required
    public Long salary;

    @Required
    public String experience;

    @Required
    public String active;

    @Formats.DateTime(pattern="yyyy-MM-dd hh:mm:yy")
    public Date created_time = new Date();

    @Formats.DateTime(pattern="yyyy-MM-dd hh:mm:yy")
    public Date modified_time ;

    @Required
    @Formats.DateTime(pattern="yyyy-MM-dd")
    public Date expire_date ;

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

    public static Jobads create(Jobads ja) {
        ja.save();  
        ja.saveManyToManyAssociations("jobcategory");    
        return ja; 
    }
}

我的观点:

<form action="@routes.JobAdController.save()" method="post" onsubmit="return checkEmpty();">
    <div class="row">
        <div class="col-md-6">
            <div class="block">
                <div class="header">
                    <h2>Create A New Job</h2>
                </div>
                <div class="content controls">
                    <div class="form-row">
                        <div class="col-md-3">Employer</div>
                        <div class="col-md-9">
                            <select class="form-control" name="employer.id" id="employer_id">
                                <option value="select">Select Employer</option>
                                @for(emp<-employersList) {
                                    <option value="@emp.id">@emp.company_name</option>
                                }
                            </select>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-md-3">Category</div>
                        <div class="col-md-9">
                            <select class="form-control" name="jobcategory.id" id="jobcategory_id">
                                <option value="select">Select Job Category</option>
                                @for(jc<-jobcategoryList) {
                                    <option value="@jc.id">@jc.name</option>
                                }
                            </select>
                        </div>
                    </div>   
                    <div class="form-row">
                        <div class="col-md-3">Location</div>
                        <div class="col-md-9">
                            <select class="form-control" name="joblocations.id" id="joblocation_id">
                                <option value="select">Select Job Location</option>
                                @for(jl<-joblocationList) {
                                    <option value="@jl.id">@jl.country,@jl.state,@jl.city</option>
                                }
                            </select>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-md-3">Job Type</div>
                        <div class="col-md-9">
                            <select class="form-control" name="jobtype" id="jobtype">
                                <option value="select">Select Job Type</option>
                                <option value="parttime">Part Time</option>
                                <option value="fulltime">Full Time</option>
                            </select>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-md-3">Title</div>
                        <div class="col-md-9"><input type="text" class="form-control" placeholder="Title" name="title" required="required"/></div>
                    </div>
                    <div class="form-row">
                        <div class="col-md-3">Text</div>
                        <div class="col-md-9"><textarea class="form-control" name="text" required="required"></textarea></div>
                    </div>
                    <div class="form-row">
                        <div class="col-md-3">salary</div>
                        <div class="col-md-9"><input type="text" class="form-control" placeholder="Salary per month"  name="salary" required="required"/></div>
                    </div>
                    <div class="form-row">
                        <div class="col-md-3">expire date</div>
                        <div class="col-md-9"><input type="date"   class="form-control" placeholder="expiry date" name="expire_date" id="expire_date"  required="required" /></div>
                        <input type="hidden"   class="form-control" placeholder="expiry date" name="exp_date" id="exp_date" />
                    </div>
                    <div class="form-row">
                        <div class="col-md-3">Active</div>
                        <div class="col-md-9">
                            <select class="form-control" name="active" id="active">
                                <option value="active">Active</option>
                                <option value="inactive">Inactive</option>
                            </select>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-md-12">
                            <button type="submit" class="btn btn-default btn-block">Add</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</form>

我的控制员:

public class JobAdController extends Controller {
    public static Result save() {

        Form<Jobads> jobadsFormData = jobadsForm.bindFromRequest();
        if (jobadsFormData.hasErrors()) {
            System.out.println("Error in form");
            return badRequest();
        } else {
            Jobads.create(jobadsFormData.get());
            return redirect(controllers.routes.JobAdController.index());
        }
    }
}

我在Jobcategory模型中没有Jobads的变量,因为我不需要它。因此,创建名为 jobads_jobcategories 的默认表。我的问题是,当我尝试在jobads表中插入数据时,它会完美插入,但映射ID不会保存在 jobads_jobcategories 表中。

3 个答案:

答案 0 :(得分:3)

由于 rtruszk 帮助我,我的jobcategorylist是空的。 Play无法将多值的变量从请求绑定到模型manytomany列表变量(我仍然试着弄清楚为什么玩这样做)

所以我为解决这个问题做了什么,我改变了form方法,从我的控制器中的url获取多值变量的值,然后创建了一个新的列表并添加到我的Form变量中。它是可选的,但我添加了getter和setter并更改了我的列表名称。代码见下文

GET 请求

public static Result save() {

    List<Long> jobCatList = new ArrayList<Long>();
    final Set<Map.Entry<String, String[]>> entries = request().queryString().entrySet();
    for (Map.Entry<String, String[]> entry : entries) {
        final String key = entry.getKey();
        final String value = Arrays.toString(entry.getValue());
        System.out.println(key + " " + value);
        if (key.equalsIgnoreCase("jobcategories.id")) {
            String val = value;
            val = val.replace("[", "");
            val = val.replace("]", "");
            String[] a = val.split(",");
            for (int i = 0; i < a.length; i++) {
                jobCatList.add(Long.parseLong(a[i].trim()));
            }
        }
    }
    List<Jobcategories> jobCatObList = new ArrayList<Jobcategories>();
    for (Long id : jobCatList) {
        System.out.println("Id are:" + id);
        jobCatObList.add(Jobcategories.findById(id));
    }
    System.out.println(request().getQueryString("jobcategories.id"));
    Form<Jobads> jobadsFormData = jobadsForm.bindFromRequest();
    System.out.println("\nCategory Form are:" + (jobadsFormData.get()).getJobcategories());
   (jobadsFormData.get()).setJobcategories(jobCatObList);
    if (jobadsFormData.hasErrors()) {
        return badRequest();
    } else {
        Jobads.create(jobadsFormData.get());
        return redirect(controllers.routes.JobAdController.index());
    }
}

OR

POST 请求

public static Result save() {

        Form<Jobads> jobadsFormData = jobadForm.bindFromRequest();

        Map<String, String[]> formUrlEncoded = request().body().asFormUrlEncoded();

        List<Jobcategories> fa = new ArrayList<Jobcategories>();


        for (String key : formUrlEncoded.keySet()) {
            String[] values = formUrlEncoded.get(key);
            for (String val : values) {
                if ("jobcategories.id".equals(key)) fa.add(Jobcategories.findById(Long.valueOf(val)));

            }
        }

            if (jobadsFormData.hasErrors()) {
            return badRequest();
        } else {
            (jobadsFormData.get()).setJobcategories(fa);

            Jobads.create(jobadsFormData.get());
            return redirect();

        }
    }

我知道这种方法不是保存多种关系的正确方法,但我没有其他选择来解决我的问题。

如果有人有更好的解决方案,那么请发布它,因为我已经尝试了好几天并且已经实现了这么多。

为什么游戏无法映射或保存多种关系?

答案 1 :(得分:2)

您的地图很好。尝试运行以下测试以确保:

@Test
public void ebeanTest() {
    FakeApplication app = Helpers.fakeApplication(Helpers.inMemoryDatabase());
    Helpers.start(app);

    Jobcategories jc = new Jobcategories();
    jc.id=1l;
    jc.title="cat 1";

    Jobads job = new Jobads();
    job.id=2l;
    job.title = "job 1";
    job.jobcategory.add(jc);
    Jobads.create(job);

    Jobads foundJob = Jobads.find.byId(2l);

    for(Jobcategories jobc:foundJob.jobcategory) {
        System.out.println("id: "+jobc.id);
        System.out.println("title: "+jobc.title);
    }       
}

您应该有以下结果:

[play-java] $ test
id: 1
title: cat 1

您还可以从Jobads类中删除以下行,因为它在那里已经过时了:

ja.saveManyToManyAssociations("jobcategory");

您的表单中似乎有错误。我想那个

jobadsFormData.get()

返回包含jobcategories空列表的Jobads。然后正确保存这样的对象。

修改 我在您的视图代码中看到您使用&#39; select&#39;用于选择Jobcategories的HTML元素。你为什么那样做?您有Jobgroup类中的Jobcategories列表,但是在&#39; select&#39;元素,您只能选择一个类别。所以这个HTML元素适合选择雇主或工作位置,但不适合选择列表。所以这就是问题所在。 &#39;选择&#39;元素映射好到fielld但不列出。

<强> EDIT2 所以你必须改变两件事:

  1. 添加多个=&#34;多个&#34;到你的HTML选择元素
  2. 检查保存表单时选择的类别。有关详细信息,请参阅this post

答案 2 :(得分:0)

尝试为jobad和/或jobcategories添加JoinColumn

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "jobads_jobcategories", joinColumns = {@JoinColumn(name="Jobads_ID", referencedColumnName="ID")})
public List<Jobcategories> jobcategory;

我想问你是否在评论中尝试,但我没有足够的声誉。