JPA / hibernate中的子查询没有返回正确的结果?

时间:2014-09-30 22:16:40

标签: hibernate jpa join subquery jpql

我在电影和演员表之间有oneToMany关联,而ManyToOne关联则相反。

我想获得给定演员的电影名称。在SQL中,此查询将为

SELECT m.name from Movie m INNER JOIN Actor a on a.movie_id=m.movie_id AND a.name='BRAD'

JPQL工作中,相同的查询将被写为

SELECT m.name from Movie m INNER JOIN m.actors act where act.name='BRAD'

此查询与上述纯SQL不同。

我希望能够执行类似的操作,因为每个Movie对象都有一组Actors

SELECT m.name from Movie m, m.actors act where BRAD' EXISTS act.names

以上查询语法错误。但它传达了我想要选择的东西。如何在不使用JOIN的情况下实现此查询,如果可能,不使用子查询。

事实上,我尝试了以下子查询版本,它也不起作用:

select m.name from Movie m Where EXISTS (SELECT act.movie FROM Actor act where act.name='Brad')

以上查询返回所有电影行

以下是我的实体中的相关部分:

    @Entity
public class Movie {

    @Id
    @Column(name="MOVIE_ID")
    @GeneratedValue
    private Long id;

    @Column(name="MovieName")
    private String name;

    @Column(name="Date_Released")
    private Date date;

    @OneToMany(mappedBy="movie",fetch=FetchType.EAGER,cascade=CascadeType.ALL)
    private Set<Actor> actors=new HashSet<>();

    public Movie(){}

    public Movie(String name, Date released){
        this.name=name;
        this.date=released;
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Set<Actor> getActors() {
        return actors;
    }

    public void setActors(Set<Actor> actors) {
        this.actors = actors;
    }

    public String toString(){
        return  id + " : " + name + " : " + date;
    }

    public void addActor(Actor a){
        getActors().add(a);
    }
}

    @Entity
public class Actor {
    @Id
    @Column(name="ACTOR_ID")
    @GeneratedValue
    private Long id;

    @Column(name="ACTOR_NAME")
    private String name;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="ACTOR_MOVIE")
    private Movie movie;


    public Actor(){}

    public Actor(String name){
        this.name=name;
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public Movie getMovie() {
        return movie;
    }

    public void setMovie(Movie movie) {
        this.movie = movie;
    }

    public String toString(){
        return name + " : " + movie.getName();
    }

}

这里的测试班:

public class HibernateTest {

    public static void main(String[] args) {

 Movie movie1 = new Movie("Mr and Mrs.Smith", new Date(2005, 6, 5));
    Actor actor3=new Actor("Brad");
    actor3.setMovie(movie1);
    Actor actor4=new Actor("Joe"); 
    actor4.setMovie(movie1);
    movie1.getActors().add(actor3);
    movie1.getActors().add(actor4);

    Movie movie = new Movie("Titanic", new Date(1997,12,19));
    Actor actor1=new Actor("Leo");
    Actor actor2=new Actor("Kate");
    actor1.setMovie(movie);
    actor2.setMovie(movie); 
    movie.getActors().add(actor1); 
    movie.getActors().add(actor2); 


   SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    Session session = sessionFactory.openSession();
    session.beginTransaction();
    session.persist(movie);
    session.persist(movie1);
    session.getTransaction().commit();
    session.close();

    session = sessionFactory.openSession();
    session.beginTransaction();
    List<String> bradMovies=session.createQuery("select m.name from Movie m, IN   (m.actors)actors"
            + " Where actors.name='BRAD'").list();
    System.out.println("bradMovies = "+ actorsFromMovies);
    session.getTransaction().commit();
    session.close();

} }

修改

我编辑了上面的代码以包含整个代码。在它只有片段之前。

1 个答案:

答案 0 :(得分:0)

这是一个没有任何JOIN和子查询的HQL查询:

Query q2 = session.createQuery("SELECT m FROM Movie m, IN (m.actors)actors 
WHERE actors.name = 'Brad'");

您问题中的以下查询也有效,但我不清楚您为什么不想使用它。

SELECT m.name from Movie m INNER JOIN m.actors act where act.name='BRAD'