Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.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多链接错误实体_Java_Hibernate_Spring Boot_Jpa - Fatal编程技术网

Java JPA多链接错误实体

Java JPA多链接错误实体,java,hibernate,spring-boot,jpa,Java,Hibernate,Spring Boot,Jpa,假设我们有4个实体:电影、工作室、站点和标签。电影、工作室和站点可以有0个或多个标记(一个标记的每个标记都有0到多个)。一部电影有0或1个站点(一个站点有0到多部电影)。一部电影有0个或多个工作室(一个工作室有0到多个电影)。我通过如下介绍TagCollection和StudioCollection实现了这些关系。TagCollection具有带电影的一对一映射,以及带Tag的多对多映射(与StudioCollection相同)。我这样做是因为: 我希望所有标记/工作室都转到同一个表,而不管它

假设我们有4个实体:电影、工作室、站点和标签。电影、工作室和站点可以有0个或多个标记(一个标记的每个标记都有0到多个)。一部电影有0或1个站点(一个站点有0到多部电影)。一部电影有0个或多个工作室(一个工作室有0到多个电影)。我通过如下介绍TagCollection和StudioCollection实现了这些关系。TagCollection具有带电影的一对一映射,以及带Tag的多对多映射(与StudioCollection相同)。我这样做是因为:

  • 我希望所有标记/工作室都转到同一个表,而不管它们附加到哪个实体
  • 链接表将有一个唯一的id返回到所属实体,这意味着当我查询关系时,我永远不必指定标记是用于电影、网站还是工作室:该id是唯一的,仅存在于一个实体
此计划失败,因为当我使用一些标记保存电影并检索它时,这些标记链接到工作室或任何其他实体,但其原始所有者除外。测试如下(后面是代码)。知道我做错了什么吗?我怀疑我的链接表中的ID是错误的,但我无法证明这一点,也看不出为什么会发生这种情况(这不是因为打字错误或做作不当)。完整的代码会在需要更多的时候发布,但下面是我的实现和失败测试的一部分。谢谢你的时间

@Test
    public void addedMoviesWithAttributesArePersisted() {
    final MovieBuilder mb = new MovieBuilder();
    mb.title("Title");

    // Add a site to the movie
    final Site site = new Site("Site TEst");
    mb.site(site);

    //Add 2 studios to the movie
    final Studio studio1 = new Studio("Studio 1");
    final Studio studio2 = new Studio("Studio 2");
    final StudioCollection studioCollection = new StudioCollection();
    studioCollection.add(Sets.newSet(studio1, studio2));
    mb.studioCollections(studioCollection);

    // Add 2 tags to the movie
    final Tag tag1 = new Tag("Tag 1");
    final Tag tag2 = new Tag("Tag 2");
    final TagCollection tagCollection = new TagCollection();
    tagCollection.add(Sets.newSet(tag1, tag2));
    mb.tagCollection(tagCollection);

    final Movie movie = mb.build();
    this.underTest.persist(movie);

    final Set<Movie> foundMovies = this.underTest.findByTitle("Title");
    assertFalse(foundMovies.isEmpty());
    assertEquals(1, foundMovies.size());
    assertTrue(foundMovies.contains(movie));
    final Movie foundMovie = foundMovies.iterator().next();

    // This fails
    assertFalse(foundMovie.getTagCollection().isEmpty());

    // Querying for all entities gives this results
    this.underTest.getAll();
    // TagCollection: id=[1] Values=[[]]
    // TagCollection: id=[2] Values=[[Tag [id=1, tagName=Tag 1], Tag [id=2, tagName=Tag 2]]]
    // TagCollection: id=[3] Values=[[]]
    // TagCollection: id=[4] Values=[[]]
    // Site: id=[1] + Name=Site TEst] + tag=[TagCollection: id=[1] Values=[[]]]
    // Studio id=[1] + Name=Studio 2] + tag=[TagCollection: id=[1] Values=[[]]]
    // Studio id=[2] + Name=Studio 1] + tag=[TagCollection: id=[2] Values=[[Tag [id=1, tagName=Tag 1], Tag [id=2, tagName=Tag 2]]]]
    // Movie: id=[1] + Title=Title] + tag=[TagCollection: id=[1] Values=[[]]]
    }
标签收集:

@Entity
@Table(name = "TAG_COLLECTION")
public class TagCollection {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
    @JoinTable(name = "tag_link", joinColumns = @JoinColumn(name = "tagCollection_id"), inverseJoinColumns = @JoinColumn(name = "tag_id"))
    private final Set<Tag> tags = new HashSet<>();

    // Getter & Setter and constructors
}
@Entity
@Table(name = "STUDIO_COLLECTION")
public class StudioCollection {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
    @JoinTable(name = "studio_link", joinColumns = @JoinColumn(name = "studioCollection_id"), inverseJoinColumns = @JoinColumn(name = "studio_id"))
    private final Set<Studio> studios = new HashSet<>();

    // Getter & Setter and constructors
}
演播室:

@Entity
@Table(name = "STUDIO")
public class Studio implements MovieEntity, Representable, Taggable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @NotNull
    @NotEmpty
    @Size(min = 1)
    @Column(unique = true, nullable = false)
    private String name;

    @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
    @JoinColumn(name = "id")
    private final TagCollection tags = new TagCollection();

    // Getter & Setter and constructors
}
工作室收藏:

@Entity
@Table(name = "TAG_COLLECTION")
public class TagCollection {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
    @JoinTable(name = "tag_link", joinColumns = @JoinColumn(name = "tagCollection_id"), inverseJoinColumns = @JoinColumn(name = "tag_id"))
    private final Set<Tag> tags = new HashSet<>();

    // Getter & Setter and constructors
}
@Entity
@Table(name = "STUDIO_COLLECTION")
public class StudioCollection {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
    @JoinTable(name = "studio_link", joinColumns = @JoinColumn(name = "studioCollection_id"), inverseJoinColumns = @JoinColumn(name = "studio_id"))
    private final Set<Studio> studios = new HashSet<>();

    // Getter & Setter and constructors
}

这似乎是您所描述的:

但你的实体似乎与你的概念模型不匹配。您可以对上述ER图进行如下建模:

@Entity
public class Tag {
    @Id @GeneratedValue private int id;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }   
    @ManyToMany private Set<Movie> movieTags;
    @ManyToMany private Set<Studio> studioTags;
    @ManyToMany private Set<Site> siteTags;

@Entity
public class Movie {
    @Id @GeneratedValue private int id;
    @ManyToMany(mappedBy="movieTags") private Set<Tag> tags;
    @ManyToOne private Studio studio;
    @ManyToOne private Site site;

@Entity
public class Site {
    @Id @GeneratedValue private int id;
    @ManyToMany(mappedBy="siteTags") private Set<Tag> tags;
    @OneToMany(mappedBy="site") private Set<Movie> movies;

@Entity
public class Studio {
    @Id @GeneratedValue private int id;
    @ManyToMany(mappedBy="studioTags") private Set<Tag> tags;
    @OneToMany(mappedBy="studio") private Set<Movie> movies;
@实体
公共类标签{
@Id@GeneratedValue private int Id;
公共int getId(){
返回id;
}
公共无效集合id(内部id){
this.id=id;
}   
@许多私人电影;
@许多私人设置的学习包;
@许多私人设置的站点标签;
@实体
公映{
@Id@GeneratedValue private int Id;
@许多(mappedBy=“movieTags”)私有设置标签;
@多通私人工作室;
@许多私人网站;
@实体
公共类网站{
@Id@GeneratedValue private int Id;
@ManyToMany(mappedBy=“siteTags”)私有集标签;
@OneToMany(mappedBy=“site”)私人电影;
@实体
公营演播室{
@Id@GeneratedValue private int Id;
@ManyToMany(mappedBy=“studioTags”)私有集标签;
@OneToMany(mappedBy=“studio”)私人电影;
并像这样使用它:

tx.begin();
Tag tag = new Tag();
Movie movie = new Movie();
Studio studio = new Studio();
Site site = new Site();

tag.setMovies(new HashSet<>(Arrays.asList(movie)));
tag.setStudios(new HashSet<>(Arrays.asList(studio)));
tag.setSites(new HashSet<>(Arrays.asList(site)));

site.setMovies(new HashSet<>(Arrays.asList(movie)));
studio.setMovies(new HashSet<>(Arrays.asList(movie)));
em.persist(movie);
em.persist(site);
em.persist(studio);
em.persist(tag);
tx.commit();
em.clear();

List<Tag> r = em.createQuery("select distinct t from Tag t left join fetch t.movieTags left join fetch t.studioTags left join fetch t.siteTags", Tag.class).getResultList();
System.out.println(r.get(0) 
        + Arrays.toString(r.get(0).getMovies().toArray())
        +":"+Arrays.toString(r.get(0).getStudios().toArray())
        +":"+Arrays.toString(r.get(0).getSites().toArray()));
tx.begin();
标签=新标签();
电影=新电影();
Studio=新建Studio();
站点=新站点();
setMovies(新的HashSet(Arrays.asList(movie));
tag.setStudios(新的HashSet(Arrays.asList(studio));
tag.setSites(新的HashSet(Arrays.asList(site));
setMovies(新的HashSet(Arrays.asList(movie));
setMovies(新的HashSet(Arrays.asList(movie));
em.persist(电影);
em.persist(site);
em.persist(工作室);
em.persist(tag);
tx.commit();
em.clear();
List r=em.createQuery(“从标记t中选择不同的t left join fetch t.movieTags left join fetch t.studioTags left join fetch t.siteTags”,Tag.class).getResultList();
System.out.println(r.get(0)
+Arrays.toString(r.get(0.getMovies().toArray())
+“:”+Arrays.toString(r.get(0.getStudios().toArray())
+“:”+Arrays.toString(r.get(0.getSites().toArray());

对于SO问题来说,这可能太复杂了。感谢您的时间和回答。它帮助我实现了我想要的
tx.begin();
Tag tag = new Tag();
Movie movie = new Movie();
Studio studio = new Studio();
Site site = new Site();

tag.setMovies(new HashSet<>(Arrays.asList(movie)));
tag.setStudios(new HashSet<>(Arrays.asList(studio)));
tag.setSites(new HashSet<>(Arrays.asList(site)));

site.setMovies(new HashSet<>(Arrays.asList(movie)));
studio.setMovies(new HashSet<>(Arrays.asList(movie)));
em.persist(movie);
em.persist(site);
em.persist(studio);
em.persist(tag);
tx.commit();
em.clear();

List<Tag> r = em.createQuery("select distinct t from Tag t left join fetch t.movieTags left join fetch t.studioTags left join fetch t.siteTags", Tag.class).getResultList();
System.out.println(r.get(0) 
        + Arrays.toString(r.get(0).getMovies().toArray())
        +":"+Arrays.toString(r.get(0).getStudios().toArray())
        +":"+Arrays.toString(r.get(0).getSites().toArray()));