【发布时间】:2021-05-20 03:41:03
【问题描述】:
我需要在 2 个实体(即项目和文章)之间设置多对多关系。 用例是一个可以链接到许多相关文章的项目。每篇文章都会链接到各种项目。 我在我的项目中使用 Spring 数据存储库,并且无法持久保存和检索与项目和文章的这种关系。
@Entity @Table(name = "projects")
@Getter @Setter
public class Project {
@Id
String id;
String name;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "project_articles",
joinColumns = { @JoinColumn(name = "project_id", referencedColumnName = "id") },
inverseJoinColumns = { @JoinColumn(name = "article_id", referencedColumnName = "id") })
private List<Article> articles = new ArrayList<>();
public Project addArticle(Article p) {
if (articles == null) articles = new ArrayList<>();
p.getProjects().add(this);
articles.add(p);
return this;
}
}
文章实体
@Entity @Table(name = "articles")
@Getter @Setter
public class Article {
@Id
String id;
String title;
String author;
String body;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "project_articles")
List<Project> projects = new ArrayList<>();
}
ProjectArticles 连接表实体。我创建它是为了解决休眠中的表创建问题。
@Entity(name = "ProjectArticles")
@Table(name = "project_articles")
@AssociationOverrides({
@AssociationOverride(name = "key.project", joinColumns = @JoinColumn(name = "project_id")),
@AssociationOverride(name = "key.article", joinColumns = @JoinColumn(name = "article_id")) }
)
@Getter @Setter
public class ProjectArticles {
@EmbeddedId ProjectArticleId key;
@Embeddable @Getter @Setter
public static class ProjectArticleId {
@Column(name = "project_id", columnDefinition = "varchar(255)")
ProjectEntity project;
@Column(name = "article_id", columnDefinition = "varchar(255)")
Article article;
}
}
这里是 spring 数据存储库。
public interface ProjectRepository extends JpaRepository<Project, String> {
public Project findProjectByName(String name);
public List<Project> findProjectByArticle(String articleId);
}
public interface ArticleRepository extends JpaRepository<Article, String> {
public List<Article> findArticlesByTitle(String title);
// NOTE: Does not work
@Query("SELECT a from Article a JOIN FETCH a.projects LEFT JOIN ProjectEntity p ON p.id = :project")
public List<Article> findArticlesByProject(@Param("project") String project);
@Query("SELECT a from Article a LEFT JOIN ProjectEntity p ON p.id = :project")
public List<Article> findArticleByProject(ProjectEntity project);
}
理想情况下,我想在服务中使用 repo,如下所示。
Article ar1 = articleRepository.save(new Article("Article title", "Author 1"));
Article ar2 = articleRepository.save(new Article("Article title 2", "Author 2"));
Article ar3 = articleRepository.save(new Article("Article title 3", "Author 3"));
Project pr1 = projectRepository.save(new Project("Project name 1"));
Project pr2 = projectRepository.save(new Project("Project name 2"));
Project pr3 = projectRepository.save(new Project("Project name 3"));
pr1.addArticle(ar1);
pr1.addArticle(ar2);
pr2.addArticle(ar1);
pr2.addArticle(ar2);
ar3.addProject(pr3);
ar3.addProject(pr1);
ar3.addProject(pr2);
articleRepository.findArticlesByProject("project-2-id");
projectRepository.findProjectByArticle("article-3-id");
但事情不工作。当我将现有文章添加到项目并保存(更新)它时,在关系表(“project_articles”)中尝试输入新行但没有项目 ID,并且出现异常。
我在这里做错了什么?我设计实体的方式有可能吗?
【问题讨论】:
标签: java hibernate jpa spring-data-jpa many-to-many