我正在使用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 表中。
答案 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());
}
}
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 强> 所以你必须改变两件事:
答案 2 :(得分:0)
尝试为jobad和/或jobcategories添加JoinColumn
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "jobads_jobcategories", joinColumns = {@JoinColumn(name="Jobads_ID", referencedColumnName="ID")})
public List<Jobcategories> jobcategory;
我想问你是否在评论中尝试,但我没有足够的声誉。