简体   繁体   English

Hibernate外键语法

[英]Hibernate Foreign Key Syntax

I am trying to learn hibernate. 我正在努力学习休眠。 I have a movie table with a foreign key to a genre table. 我有一个带有流派表的外键的电影表。 Each movie is assigned to a single genre. 每部电影都分配到一个类型。 Each genre may be assigned to many movies. 每种类型都可以分配给许多电影。

Here are the table definitions: 以下是表定义:

CREATE TABLE `movie` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(64) NOT NULL,
  `genre_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_genre` (`genre_id`),
  CONSTRAINT `fk_genre` FOREIGN KEY (`genre_id`) REFERENCES `genre` (`id`) ON UPDATE CASCADE,

)

CREATE TABLE IF NOT EXISTS `genre` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) 

For code I have 对于我有的代码

@Entity
public class Movie implements java.io.Serializable {

    private static final long serialVersionUID = 1;
    private Integer id;
    private String title;
    private Genre genre;
    ...

    @ManyToOne
    public Genre getGenre() {
        return genre;
    }

Also

@Entity
public class Genre implements java.io.Serializable {

    private static final long serialVersionUID = 1;
    private Integer id;
    private String name;

    @Id
    @GeneratedValue
    @Column(name = "id")
    public Integer getId() {
       return this.id;
    }

Then the select generated by hibernate looks like 然后由hibernate生成的选择看起来像

select
    movie0_.id as column1_4_,
    movie0_.genre_id as genre11_4_,
    movie0_.title as title4_
from
    Movie movie0_

And this not right as there's no reference to the genre table. 这不对,因为没有对类型表的引用。 The correct query should have a join with the genre table. 正确的查询应该与流派表连接。 More like 更像

select
    movie0_.id as column1_4_,
    genre.name as genre11_4_,
    movie0_.title as title4_
from
    Movie movie0_, Genre genre
where
    movie0_.genre_id = genre.id;

I'm a little bit of a loss as to what I'm doing wrong. 对于我做错了什么,我有点失落。 Should the many to one annotation be in the Genre class instead of the Movie class? 多对一注释应该是Genre类而不是Movie类吗? Or do you see anything else that I'm doing wrong? 或者你看到其他任何我做错了吗?

Based on the advise below, Movie now has 根据以下建议,电影现在有

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append(id).append(" ");
    sb.append(title).append(" ");

    this.getGenre(); //new

    sb.append(genre.getName());
    return sb.toString();
}

@ManyToOne(fetch=FetchType.EAGER) //new
public Genre getGenre() {
    return genre;
}

And the way I'm loading Movie is through 我正在加载电影的方式是通过

public static void main(String[] args) {
    SessionFactory sf = HibernateUtil.getSessionFactory();
    Session session = sf.openSession();
    List<Movie> movies = session.createQuery("from Movie").list();
    for (Movie movie : movies) {
        System.out.println(movie.toString());
    }
    session.close();
}

What I'm seeing is that even though I have the eager load and I'm explicitly saying getGenre in toString, no query is generated and I'm just getting a null back. 我所看到的是,即使我有急切的负载,我明确地在toString中说getGenre,也没有生成任何查询,我只是得到一个null。

When you use HQL syntax (eg createQuery("from Movie") ), then Hibernate/JPA will only fetch the Genre entity when you call getGenre() on your Movie object. 当您使用HQL语法(例如createQuery("from Movie") )时,Hibernate / JPA将仅在您对Movie对象调用getGenre()时获取Genre实体。 This is called "lazy fetching". 这被称为“懒人取物”。 When the method is called, Hibernate will issue another query to fetch the Genre . 调用该方法时,Hibernate将发出另一个查询来获取Genre

Note that HQL queries ignore the FetchType on your annotations - HQL is used to tell Hibernate exactly what to do, rather than using the hints in the annotations. 请注意,HQL查询会忽略注释上的FetchType - HQL用于告诉Hibernate 到底要做什么,而不是使用注释中的提示。

To make it fetch the Genre in the same query as the Movie , you need to tell it to: 为了使它获取Genre的查询相同的Movie ,你需要告诉它:

createQuery("from Movie m join fetch m.genre")

try this: 尝试这个:

Moive side: Moive方面:

@ManyToOne
@JoinColumn(name = "genre_id")
public Genre getGenre() {..}

and on the other side (genre): 在另一边(类型):

@OneToMany(mappedBy="genre")
List/Set getMovies(){..}

then you can from a movie object movie.getGenre() get Genre. 那么你可以从一个电影对象movie.getGenre()得到流派。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM