2016-06-12 16 views
-1

テーブルAはテーブルBとの関係があり、と1対多数という関係があるとします。 私がしたいのは、テーブルAからの制限と選択した結果テーブルへの参加後に選択を行うことですB。 私は問題を直面していますか?Hibernate:ネイティブSQL + addEntity()を使用

典型的なCriteria.selectMaxResultsそれは私が必要とするものではなく、結合後に受け入れられ、テーブルから10の異なる行を得る代わりに許容されます。Aたとえば、テーブルAから10行テーブルB

(1)それを行うにはどうすればよいですか? 1つのクエリでAのユニークな行のみを選択し、他のクエリではAと結合を選択しますB?私はsession.createSQLQuery(sQuery)を使用しようとしたチュートリアルやドキュメントを休止状態に応じて、だから、

String sQuery = SELECT a.*,b* FROM (SELECT * FROM parentTable WHERE c.id=777 LIMIT 0,10) AS a, b.* WHERE a.id=b.a_id; 

:一般的に

は、ネイティブSQL言語に、私は次のクエリを実行することを期待します。私の方法は次のように見えます:

@Override 
@Transactional 
public List<VocabularyWord> getWords(int vocId, int firstResult, int pageSize) { 
    Session s = this.template.getSessionFactory().getCurrentSession(); 
    SQLQuery query = s.createSQLQuery("SELECT {vW.*}, m.* FROM (SELECT * FROM vocabulary_words AS vw WHERE vw.vocabulary_id=:id LIMIT :from,:size) AS vW, meaning AS m WHERE vW.id=m.vocabulary_words_id;"); 
    query.setInteger("id", vocId); 
    query.setInteger("from", firstResult); 
    query.setInteger("size", pageSize); 
    query.addEntity("vW", VocabularyWord.class); 
    query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
    // If unccoment the next word I get error: Column 'id1_1_1_' not found. But as I'have understood I don't need this. 
    // query.addEntity("m", Meaning.class); 
    List l = query.list(); 
    return l; 
} 

そして、このメソッドは私が望むものを返します。しかし、この結果を返すために、Hibernateは膨大な量のクエリを実行します。 (彼は(1)のような何かをしようとする?)。ビーイング正確Hibernateが実行される5次照会:

Hibernate: 
    SELECT 
     vW.id as id1_7_0_, 
     vW.original_text as original2_7_0_, 
     vW.transcription as transcri3_7_0_, 
     vW.vocabulary_id as vocabula4_7_0_, 
     m.* 
    FROM 
     (SELECT 
      * 
     FROM 
      vocabulary_words AS vw 
     WHERE 
      vw.vocabulary_id=? LIMIT ?,?) AS vW, 
     meaning AS m 
    WHERE 
     vW.id=m.vocabulary_words_id; 
Hibernate: 
    select 
     meaning0_.vocabulary_words_id as vocabula5_1_0_, 
     meaning0_.id as id1_1_0_, 
     meaning0_.id as id1_1_1_, 
     meaning0_.definition as definiti2_1_1_, 
     meaning0_.example as example3_1_1_, 
     meaning0_.translation as translat4_1_1_, 
     meaning0_.vocabulary_words_id as vocabula5_1_1_, 
     meaning0_.w_type as w_type6_1_1_ 
    from 
     meaning meaning0_ 
    where 
     meaning0_.vocabulary_words_id=? 
Hibernate: 
    select 
     meaning0_.vocabulary_words_id as vocabula5_1_0_, 
     meaning0_.id as id1_1_0_, 
     meaning0_.id as id1_1_1_, 
     meaning0_.definition as definiti2_1_1_, 
     meaning0_.example as example3_1_1_, 
     meaning0_.translation as translat4_1_1_, 
     meaning0_.vocabulary_words_id as vocabula5_1_1_, 
     meaning0_.w_type as w_type6_1_1_ 
    from 
     meaning meaning0_ 
    where 
     meaning0_.vocabulary_words_id=? 
Hibernate: 
    select 
     meaning0_.vocabulary_words_id as vocabula5_1_0_, 
     meaning0_.id as id1_1_0_, 
     meaning0_.id as id1_1_1_, 
     meaning0_.definition as definiti2_1_1_, 
     meaning0_.example as example3_1_1_, 
     meaning0_.translation as translat4_1_1_, 
     meaning0_.vocabulary_words_id as vocabula5_1_1_, 
     meaning0_.w_type as w_type6_1_1_ 
    from 
     meaning meaning0_ 
    where 
     meaning0_.vocabulary_words_id=? 
Hibernate: 
    select 
     meaning0_.vocabulary_words_id as vocabula5_1_0_, 
     meaning0_.id as id1_1_0_, 
     meaning0_.id as id1_1_1_, 
     meaning0_.definition as definiti2_1_1_, 
     meaning0_.example as example3_1_1_, 
     meaning0_.translation as translat4_1_1_, 
     meaning0_.vocabulary_words_id as vocabula5_1_1_, 
     meaning0_.w_type as w_type6_1_1_ 
    from 
     meaning meaning0_ 
    where 
     meaning0_.vocabulary_words_id=? 

マイVocabularyWordエンティティ

public class VocabularyWord implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id", updatable = false, nullable = false) 
    private int id; 
    @Column(name = "vocabulary_id", updatable = false, nullable = false) 
    private int vocId; 
    @Column(name = "original_text", nullable = false) 
    private String originalText; 
    @Column(name="transcription", nullable = true) 
    private String transcription; 
    @OneToMany (mappedBy = "vocWord", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    private Set<Meaning> meaning; 

    // + getters and setters 
} 

マイ意味エンティティ

public class Meaning implements Serializable { 
    @Id 
    @Column(name = "id", updatable = false, nullable = false) 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int id; 
    @JsonIgnore 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "vocabulary_words_id", nullable = false, updatable = false) 
    private VocabularyWord vocWord; 
    @JsonIgnore 
    @Column(name = "vocabulary_words_id", updatable = false, insertable = false) 
    private int vocWordId; 
    @Column(name = "w_type", nullable = true, unique = false) 
    private String wType; 
    @Column(name = "example", nullable = true, unique = false) 
    private String example; 
    @Column(name = "definition", nullable = true, unique = false) 
    private String definition; 
    @Column(name = "translation", nullable = true, unique = false) 
    private String translation; 
    //+ getters and setters 
} 

私はこの問題を解決するにはどうすればよいです?または、おそらく、私はそのクエリを実現するために他の方法を選んでいますか?

私は、助け、提案、アイデア、および関連リンクを感謝します。前もって感謝します。

答えて

0

質問を変更して.addJoin().addRootEntity()を追加して問題を解決しました。だから今、私の方法のgetWordsは、次なります

@Override 
@Transactional 
public List<VocabularyWord> getWords(int vocId, int firstResult, int pageSize) { 
Session s = this.template.getSessionFactory().getCurrentSession(); 
SQLQuery query = s.createSQLQuery("SELECT {vW.*}, {m.*} FROM (SELECT * FROM vocabulary_words AS vw WHERE vw.vocabulary_id=:id LIMIT :from,:size) AS vW LEFT JOIN meaning AS m ON (m.vocabulary_words_id = vW.id);"); 
query.addEntity("vW", VocabularyWord.class) 
.addJoin("m", "vW.meaning") 
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 
.setInteger("id", vocId) 
.setInteger("from", firstResult) 
.setInteger("size", pageSize); 
query.addRoot("vW", VocabularyWord.class); 
List l = query.list(); 
return l; 
} 

この方法は、正確に一つのクエリを実行します:

Hibernate: 
    SELECT 
     vW.id as id1_7_0_, 
     vW.original_text as original2_7_0_, 
     vW.transcription as transcri3_7_0_, 
     vW.vocabulary_id as vocabula4_7_0_, 
     m.vocabulary_words_id as vocabula6_1_0__, 
     m.id as id1_1_0__, 
     m.id as id1_1_1_, 
     m.definition as definiti2_1_1_, 
     m.example as example3_1_1_, 
     m.translation as translat4_1_1_, 
     m.vocabulary_words_id as vocabula6_1_1_, 
     m.w_type as w_type5_1_1_ 
    FROM 
     (SELECT 
      * 
     FROM 
      vocabulary_words AS vw 
     WHERE 
      vw.vocabulary_id=? LIMIT ?,?) AS vW 
    LEFT JOIN 
     meaning AS m 
      ON (
       m.vocabulary_words_id = vW.id 
      ); 
関連する問題