Playframework manytomany关系无法在play framework的映射表中保存映射id

Playframework manytomany关系无法在play framework的映射表中保存映射id,playframework,many-to-many,ebean,Playframework,Many To Many,Ebean,我正在使用play2.2.1,试图在Jobads和JobCategory模型之间创建一个多个关系 MyJobads.java package models; @Entity public class Jobads extends Model { @Id public Long id; @ManyToOne public Employers employer; @ManyToMany(cascade = CascadeType.ALL) @J

我正在使用play2.2.1,试图在JobadsJobCategory模型之间创建一个多个关系

MyJobads.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; 
    }
}
封装模型;
@实体
公共类职务广告扩展模型{
@身份证
公共长id;
@许多酮
公共雇主;
@多个(级联=级联类型.ALL)
@JoinTable(name=“jobads\u jobcategories”)
公开名单工作类别;
@许多酮
公共工作场所;
@必需的
公共字符串作业类型;
@必需的
公共字符串标题;
@必需的
公共字符串文本;
@必需的
公共长期工资;
@必需的
公众弦经验;
@必需的
公共字符串处于活动状态;
@格式.日期时间(pattern=“yyy-MM-dd-hh:MM:yy”)
创建的公共日期_时间=新日期();
@格式.日期时间(pattern=“yyy-MM-dd-hh:MM:yy”)
公共日期和时间;
@必需的
@格式.日期时间(pattern=“yyyy-MM-dd”)
公开日期到期日;
公共静态查找器find=新查找器(
长类,工作类
);
公共静态Jobads创建(Jobads ja){
ja.save();
ja.储蓄互助协会(“工作类别”);
返回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>

创建新作业
雇主
选择雇主
@对于(emp请尝试为Jobad和/或jobcategories添加JoinColumn)

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "jobads_jobcategories", joinColumns = {@JoinColumn(name="Jobads_ID", referencedColumnName="ID")})
public List<Jobcategories> jobcategory;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name=“jobads\u jobcategories”,joinColumns={@JoinColumn(name=“jobads\u ID”,referencedColumnName=“ID”)})
公开名单工作类别;

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

你的映射很好。请尝试运行以下测试以确保:

@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。然后正确保存该对象

编辑 我在您的查看代码中看到,您使用“选择”HTML元素来选择工作类别。为什么这样做?您的Jobads类中有工作类别列表,但在“选择”元素中,您只能选择一个类别。因此,此HTML元素适用于选择雇主或工作地点,但不适用于选择列表。因此,问题就出在这里。“选择”元素这张地图很好地映射到fielld,但不用于列表

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

  • 向HTML选择元素添加multiple=“multiple”
  • 检查保存表单时选择的类别。有关详细信息,请参阅

  • 由于rtruszk的帮助,我的工作分类列表是空的。 Play无法将多值变量从request绑定到models manytomy list变量(我仍在试图弄清楚Play为什么这么做)

    为了解决这个问题,我改变了表单方法,从控制器中的url获取多值变量的值,然后创建了一个新列表并添加到表单变量中。这是可选的,但我添加了getter和setter,并更改了列表名。下面给出了代码

    对于获取请求

    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());
        }
    }
    
    公共静态结果保存(){
    List jobCatList=new ArrayList();
    最终设置条目=请求().queryString().entrySet();
    对于(Map.Entry:entries){
    最后一个字符串key=entry.getKey();
    最终字符串值=Arrays.toString(entry.getValue());
    System.out.println(键+“”+值);
    if(key.equalsIgnoreCase(“jobcategories.id”)){
    字符串val=值;
    val=val.replace(“[”,”);
    val=val.replace(“]”,“”);
    字符串[]a=val.split(“,”);
    for(int i=0;i
    或 对于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();
    
            }
        }
    
    公共静态结果保存(){
    表单jobadsFormData=jobadForm.bindFromRequest();
    Map formUrlEncoded=request().body().asFormUrlEncoded();
    List fa=new ArrayList();
    for(字符串键:formUrlEncoded.keySet()){
    字符串[]值=formUrlEncoded.get(键);
    for(字符串值:值){
    if(“jobcategories.id”.equals(key))fa.add(jobcategories.findById(Long.valueOf(val));
    }
    }
    if(jobadsFormData.hasErrors()){
    返回请求();
    }否则{
    (jobadsFormData.get()).setJobcategories(fa);
    create(jobadsFormData.get());
    返回重定向();
    }
    }
    
    我知道这种方法不是保存很多关系的正确方法,但我没有任何其他选择来解决我的问题

    如果有人有更好的解决方案,那就发吧,因为我已经尝试了好几天了,已经取得了很大的成就

    为什么play不能映射或sav
    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();
    
            }
        }