2012-02-10 18 views
3

私は休止状態を学習しようとしています。私は、ジャンルテーブルへの外部キーを持つムービーテーブルを持っています。各ムービーは1つのジャンルに割り当てられます。各ジャンルは多くの映画に割り当てられることがあります。ここでHibernateの外部キーの構文

がテーブル定義している:私はインクルードが休止状態で生成されたSELECTまた

@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; 
    } 

その後

@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; 
    } 

持っているコードの場合

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`) 
) 

select 
    movie0_.id as column1_4_, 
    movie0_.genre_id as genre11_4_, 
    movie0_.title as title4_ 
from 
    Movie movie0_ 
のように見えます

これは正しくないので、ジャンルテーブルへの参照はありません。正しいクエリには、ジャンルテーブルとの結合が必要です。もっと似ている

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; 

私は間違って何をしているのか、少し迷っています。ムービークラスではなく、複数のアノテーションをGenreクラスに入れる必要がありますか?それとも、私が間違っていることが他にもありますか?下記のアドバイスに基づいて

、映画は今

@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; 
} 

を持っていると私ムービーをロードしています方法は、私が見ていることである

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(); 
} 

ていること、私は熱心を持っているにもかかわらずロードと私は明示的にgetGenre toStringで、クエリが生成されていないと私はちょうど戻ってきています。あなたはHQLの構文(例えばcreateQuery("from Movie"))を使用すると、あなたのMovieオブジェクトにgetGenre()を呼び出すとき

+0

'Movie'オブジェクトをどのように取得していますか?それを行うために使用しているコードを表示してください。 – skaffman

+0

私は上記の説明をあなたの提案であるskaffmanに応じて編集しました。 –

答えて

0

は、その後、休止状態/ JPAはGenreエンティティを取得します。これは「遅延フェッチ」と呼ばれます。メソッドが呼び出されると、Hibernateは別のクエリを発行してGenreを取得します。 HQLクエリーがあなたの注釈にFetchTypeを無視

注 - HQLはが正確ではなく、注釈にヒントを使用するよりも、何をすべきかをHibernateに伝えるために使用されます。

それはMovieと同じクエリでGenreをフェッチするようにするには、あなたがそれを伝える必要があります:

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

はOneToOneではなく、ManyToOnesはデフォルトでEAGERに設定されていますか? – SelimOber

+0

@SelimOber:大丈夫です。それに応じて編集。 – skaffman

+0

これも機能しました!そして、私はhttp://clippy.tk/index.php?show=1036でファイルの良いバージョンを投稿しました。 –

0

はこれを試してみてください。

Moive側:

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

をし、反対側(ジャンル):

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

ムービーオブジェクトmovie.getGenre()からジャンルを取得できます。

+0

ジャンル側のマッピングは必要ありません。 joinColumnアノテーションで試してみることをお勧めします – steffinchen

+0

これはうまくいきました!私はhttp://clippy.tk/index.php?show=1035で誰かを助けるかもしれないという希望ですべてのファイルを投稿しました。 –

関連する問題