我有两个实体人物和电影。
@Entity
public class Person {
..some fields
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "actors")
@OrderBy("id")
private Set<Movie> moviesActor = new TreeSet<>();
}
@Entity
public class Movie {
..fields
@JoinTable(name = "actor_movie",
joinColumns = { @JoinColumn(name = "movie_id") },
inverseJoinColumns = { @JoinColumn(name = "actor_id") })
private Set<Person> actors = new TreeSet<>();
}
有很多关系,所以有新的表actor_movie来保持它。我怎样才能让每一个拥有任何电影的人都得到它?所以我想要实现的是获取actor_movie表中存在的每个人。我尝试使用Spring数据jpa但找不到正确的查询。
答案 0 :(得分:0)
由于您使用的是Letch类型,您需要使用join fetch来获取moviesActor。
您可以将jpql与spring数据一起使用。 我尚未测试下面的查询,但应该可以使用。
public interface PersonRepository extends JpaRepository<Person, Long> { //Long if Person.id is of type Long
@Query("SELECT p FROM Person p LEFT JOIN FETCH p.moviesActor WHERE size(p.moviesActor) > 0");
List<Person> findActors1();
// Or
@Query("SELECT p FROM Person p JOIN FETCH p.moviesActor");
List<Person> findActors2();
}
有关jpql size()运算符的更多信息,请访问:https://www.thoughts-on-java.org/jpql/
答案 1 :(得分:0)
您可以直接使用join:
@Query("SELECT p FROM Person p JOIN p.moviesActor movie");
列出findPersonHasMovie();
答案 2 :(得分:0)
实体关系最佳做法:
fetch = FetchType.LAZY
。JOIN FETCH
查询。LazyInitializationException
的休眠状态。spring.jpa.open-in-view=false
示例:
由Spring Data JPA和Hibernate作为JPA Provider。
实体:
public class Blog{
...
@ManyToMany(fetch = FetchType.LAZY) //default is LAZY in ManyToMany
@JoinTable(name="blog_tag",
joinColumns = @JoinColumn(name = "blog_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
@OrderBy //order by tag id
private Set<Tag> tags = new HashSet<>();
//2 utility methods in owner side
public void addTag(Tag tag){
tags.add(tag);
tag.getBlogs().add(this);
}
public void removeTag(Tag tag){
tags.remove(tag);
tag.getBlogs().remove(this);
}
//override equals & hashcode
}
public class Tag {
...
@ManyToMany(mappedBy = "tags")
private Set<Blog> blogs = new HashSet<>();
//override equals & hashcode
}
现在,假设您想获取一个包含标签项的博客:
存储库:
@Repository
public interface BlogRepository extends JpaRepository<Blog, Long> {
@Query("select b from Blog b join fetch b.tags where b.name = :name")
Blog getBlog(@Param("name") String blogName);
}
服务:
public interface BlogService {
Blog getBlog(String blogName);
}
@Service
public class BlogServiceImpl implements BlogService{
@Autowired
private BlogRepository blogRepository;
@Override
public Blog getBlog(String blogName) {
return blogRepository.getBlog(blogName);
}
}
答案 3 :(得分:-1)
在Person和Movie之间只需要一个JOIN
。由于Hibernate抽象出中间表的存在,所以你不必担心它。
所以,使用Spring Data Repository:
class PersonRepository extends CrudRepository<Person, Long> {
List<Person> findByMoviesActor();
}
使用Jpql:
SELECT person FROM Person person JOIN person.moviesActor movie