Hibernate:使用本机SQL + addEntity()

时间:2016-06-12 22:50:08

标签: java mysql spring hibernate

我的表格gifs与表格A的关系为一对多。 我想要做的是从表B中选择具有іщьу限制并在加入选定结果表A之后。 所以我遇到了一个问题,如何以正确的方式进行休眠?

典型的B不是我需要的,因为加入后限制将接受而不是从表Criteria.selectMaxResults获得10个不同的行我将从表'A获得例如1行'加入了表A中的10个不同的行。

(1)那么最好的方法是什么?在一个查询中仅选择B中的唯一行,而在另一个查询中,选择A并加入A

通常,在本机SQL语言中,我希望执行下一个查询:

B

所以,根据hibernate教程和文档,我尝试使用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; 。我的方法以下一个方式看待:

session.createSQLQuery(sQuery)

这种方法正是我想要的。但要返回此结果,hibernate会执行大量查询。 (他试图做(1)?)。完全 Hibernate执行5次下一次查询

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

我的 VocabularyWord实体

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=?

我的含义实体

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
}

我该如何解决这个问题?或者,我可能选择其他方式来实现该查询吗?

我将感谢任何帮助,主张,想法和相关链接。提前谢谢。

1 个答案:

答案 0 :(得分: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
            );