Play Framework 1.2.5 JPA 中的多对多关系

3

我有两个模型:Article.javaTags.java。一个Article可以有多个Tags,而一个Tags可以属于多个Article。我现在在使用JPA和Play Framework 1.2.5建立这种关系时遇到了麻烦。以下是我的代码(没有setter-getter),实际上它能工作,尽管会抛出异常,但我无法获取ArticleTagsgetTagname())。

Article article = Article.findById((long)id);
List<Tags> tags = article.getTags();

for (Tags tags2 : tags) {
    System.out.println(tags2.getTagname());
}

这是我的模型,Article.java
@Entity
public class Article extends Model{

    @Required
    public String title;

    @Required
    public String link;

    @Required
    @Lob
    public String description;

    public Date date;

    @ManyToMany(cascade=CascadeType.ALL)
    public List<Tags> tags = new ArrayList<Tags>();
}

Tags.java

@Entity
public class Tags extends Model {

    @Required
    public String tagname;

    @ManyToMany(mappedBy="tags") 
    public List<Article> tagsInArticle = new ArrayList<Article>(); 
}

1
“我无法获取标签”是什么意思?会发生什么?有任何异常吗?如果有,堆栈跟踪是什么? - JB Nizet
1个回答

2

我正在做类似于你提供的代码(并使用Play 1.2.5),但是似乎发现了你提供的代码存在问题。以下是我的步骤:

首先,我创建了两个模型Article.java

package models;

import play.data.validation.Required;
import play.db.jpa.Model;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "article")
public class Article extends Model {
    @Required
    public String title;

    @ManyToMany(cascade = CascadeType.ALL)
    public List<Tag> tags = new ArrayList<Tag>();
}

以及Tag.java

package models;

import play.data.validation.Required;
import play.db.jpa.Model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "tag")
public class Tag extends Model {
    @Required
    @Column(name = "tag_name")
    public String tagName;

    @ManyToMany(mappedBy = "tags")
    public List<Article> articles = new ArrayList<Article>();
}

接下来,在数据库中,我手动添加了几条记录进行测试:

文章(id;title)> 1;"java示例"和6;"文章1"

标签(id;tag_name)> 4;"java"和5;"playframework"

文章标签(articles_id;tags_id)> 6;4和6;5和1;4

然后,我使用控制器操作进行测试:

public static void test() {
    Article article = Article.findById(6L); // find "article1"
    Tag tag_java = Tag.findById(4L); // find java tag
    render(article, tag_java);
}

请查看以下内容:

#{extends 'main.html' /}

<h3>Article Title : ${article?.title}</h3>

Tags:<br>
<ol>
#{list article?.tags, as:'tag'}
    <li>${tag.tagName}</li>
#{/list}
</ol>

All article tagged <b>java</b> :
<ul>
#{list tag_java?.articles, as:'java_article'}
    <li>${java_article.title}</li>
#{/list}
</ul>

最后,结果是预期的:

result


更新

这个@ManyToOne关系是双向的。提供单个数据文章,我们可以得到该文章上的所有标签,同时所有这些标签都可以有对应每个标签的所有文章数据。控制器代码类似,但不直接传递Tag对象,视图如下:

#{extends 'main.html' /}

<h3>Article Title : ${article?.title}</h3>

Tags:<br>
<ol>
#{list article?.tags, as:'tag'}
    <li>${tag.tagName}</li>
#{/list}
</ol>

#{list article?.tags, as:'tag'}
Related article [tagged with ${tag.tagName}]:<br>
<ol>
    #{list tag?.articles, as:'article'}
        <li>${article.title}</li>
    #{/list}
</ol>
#{/list}

bi-directional rel


但是,朋友,看起来这样做是没有用的。你为什么要尝试使用findById获取标签呢?这意味着你的表之间没有关系。我需要有人告诉我如何在双方设置ManyToMany关系,以便我可以查询不仅此文章的所有标签,还有所有拥有此标签的文章。 - Emilla
是的朋友,使用@ManyToMany可以使关系双向。请参见我上面更新的答案。抱歉回复晚了。 - Wayan Wiprayoga

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接