Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA ManToMany关联和使用Spring数据存储库插入、检索数据_Java_Hibernate_Jpa_Spring Data Jpa_Many To Many - Fatal编程技术网

Java JPA ManToMany关联和使用Spring数据存储库插入、检索数据

Java JPA ManToMany关联和使用Spring数据存储库插入、检索数据,java,hibernate,jpa,spring-data-jpa,many-to-many,Java,Hibernate,Jpa,Spring Data Jpa,Many To Many,我需要设置两个实体之间的多对多关系,即项目和文章。 用例是一个可以链接到许多相关文章的项目。因此,每篇文章都将链接到不同的项目。 我在项目中使用Spring数据存储库,在持久化和检索与项目和文章的这种关系方面遇到了问题 @Entity @Table(name = "projects") @Getter @Setter public class Project { @Id String id; String name; @ManyToMany(

我需要设置两个实体之间的多对多关系,即项目和文章。 用例是一个可以链接到许多相关文章的项目。因此,每篇文章都将链接到不同的项目。 我在项目中使用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;
    }
}
以下是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);
}
但事情并不成功。当我将现有文章添加到项目并保存(更新)它时,在关系表(“project_articles”)中,新行尝试输入,但没有项目id,我得到一个异常


我做错了什么?有可能是我设计实体的方式吗?

CascadeType.PERSIST的主要思想是创建实体实例,设置必要的双边关系(Project->ArticlesArticle->Projects),然后保存到数据库。如果保存所有项目,则由于
CascadeType.PERSIST
和实体关系,项目将隐式保存

试试这个

@Transactional
public void save() {
    Article ar1 = new Article("Article title", "Author 1");
    Article ar2 = new Article("Article title 2", "Author 2");
    Article ar3 = new Article("Article title 3", "Author 3");

    Project pr1 = new Project("Project name 1");
    Project pr2 = new Project("Project name 2");
    Project pr3 = new Project("Project name 3");

    pr1.addArticle(ar1);
    pr1.addArticle(ar2);
    pr1.addArticle(ar3);

    pr2.addArticle(ar1);
    pr2.addArticle(ar2);
    pr2.addArticle(ar3);

    pr3.addArticle(ar3);

    projectRepository.saveAll(Arrays.asList(pr1, pr2, pr3));
}

我已经按照几篇博客文章中描述的指导方针解决了这个问题

此外,我还需要解决JSON序列化和有限递归问题

这是最终的JPA模型

@Entity @Table(name = "projects")
@Getter @Setter
public class Project {
    @Id
    String id;
    String name;

    @JsonIgnoreProperties("projects")
    @ManyToMany(cascade = { PERSIST, MERGE, DETACH, REFRESH }, fetch = FetchType.LAZY)
    @JoinTable(name = "project_articles",
        joinColumns = { @JoinColumn(name = "project_id", referencedColumnName = "id") },
        inverseJoinColumns = { @JoinColumn(name = "article_id", referencedColumnName = "id") })
    private Set<Article> articles = new HashSet<>();

    public Project addArticle(Article art) {
        articles.add(art);
        art.getProjects().add(this);
        return this;
    }
}

但仍然需要解决数据获取问题。e、 g.将所有项目链接到一个项目。(待办事项

检查我的答案。我想我明白你想说什么,但你的解决方案不完整。谢谢你的回复。我已经对答案做了解释
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");
@Transactional
public void save() {
    Article ar1 = new Article("Article title", "Author 1");
    Article ar2 = new Article("Article title 2", "Author 2");
    Article ar3 = new Article("Article title 3", "Author 3");

    Project pr1 = new Project("Project name 1");
    Project pr2 = new Project("Project name 2");
    Project pr3 = new Project("Project name 3");

    pr1.addArticle(ar1);
    pr1.addArticle(ar2);
    pr1.addArticle(ar3);

    pr2.addArticle(ar1);
    pr2.addArticle(ar2);
    pr2.addArticle(ar3);

    pr3.addArticle(ar3);

    projectRepository.saveAll(Arrays.asList(pr1, pr2, pr3));
}
@Entity @Table(name = "projects")
@Getter @Setter
public class Project {
    @Id
    String id;
    String name;

    @JsonIgnoreProperties("projects")
    @ManyToMany(cascade = { PERSIST, MERGE, DETACH, REFRESH }, fetch = FetchType.LAZY)
    @JoinTable(name = "project_articles",
        joinColumns = { @JoinColumn(name = "project_id", referencedColumnName = "id") },
        inverseJoinColumns = { @JoinColumn(name = "article_id", referencedColumnName = "id") })
    private Set<Article> articles = new HashSet<>();

    public Project addArticle(Article art) {
        articles.add(art);
        art.getProjects().add(this);
        return this;
    }
}
@Entity @Table(name = "articles")
@Getter @Setter
public class Article {

    @Id
    String id;
    String title;
    String author;
    String body;

    @JsonIgnoreProperties("articles")
    @ManyToMany(mappedBy = "articles", cascade = { PERSIST, MERGE, DETACH, REFRESH }, fetch = FetchType.LAZY)
    Set<Project> projects = new HashSet<>();

    public Article addProject(Project prj) {
        projects.add(prj);
        prj.getArticles().add(this);
        return this;
    }    
}
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"));

/* Link articles 1 and 3 to project 1 */
pr1.getArticles().add(ar1);
pr1.getArticles().add(ar3);
ar1.getProjects().add(pr1);
ar3.getProjects().add(pr1);

/* Link articles 2 and 3 to project 2 */
pr2.addArticle(ar3);
pr2.addArticle(ar2);

/* Link project 3 to article 3 */
ar3.addProject(pr3);