Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lect17-hibernate-orm / more / hibernate_reference.pdf
Скачиваний:
54
Добавлен:
18.03.2015
Размер:
2.2 Mб
Скачать

Returning multiple entities

sess.createSQLQuery("SELECT c.ID, NAME, BIRTHDATE, DOG_ID, D_ID, D_NAME FROM CATS c, DOGS d

WHERE c.DOG_ID = d.D_ID")

.addEntity("cat", Cat.class)

.addJoin("cat.dog");

In this example, the returned Cat's will have theirdog property fully initialized without any extra roundtrip to the database. Notice that you added an alias name ("cat") to be able to specify the target property path of the join. It is possible to do the same eager joining for collections, e.g. if the Cat had a one-to-many to Dog instead.

sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE, D_ID, D_NAME, CAT_ID FROM CATS c, DOGS d WHERE c.ID = d.CAT_ID")

.addEntity("cat", Cat.class)

.addJoin("cat.dogs");

At this stage you are reaching the limits of what is possible with native queries, without starting to enhance the sql queries to make them usable in Hibernate. Problems can arise when returning multiple entities of the same type or when the default alias/column names are not enough.

18.1.4. Returning multiple entities

Until now, the result set column names are assumed to be the same as the column names specified in the mapping document. This can be problematic for SQL queries that join multiple tables, since the same column names can appear in more than one table.

Column alias injection is needed in the following query (which most likely will fail):

sess.createSQLQuery("SELECT c.*, m.* FROM CATS c, CATS m WHERE c.MOTHER_ID = m.ID")

.addEntity("cat", Cat.class)

.addEntity("mother", Cat.class)

The query was intended to return two Cat instances per row: a cat and its mother. The query will, however, fail because there is a conflict of names; the instances are mapped to the same column names. Also, on some databases the returned column aliases will most likely be on the form "c.ID", "c.NAME", etc. which are not equal to the columns specified in the mappings ("ID" and "NAME").

The following form is not vulnerable to column name duplication:

sess.createSQLQuery("SELECT {cat.*}, {m.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = m.ID")

.addEntity("cat", Cat.class)

.addEntity("mother", Cat.class)

This query specified:

299

Chapter 18. Native SQL

the SQL query string, with placeholders for Hibernate to inject column aliases

the entities returned by the query

The {cat.*} and {mother.*} notation used above is a shorthand for "all properties". Alternatively, you can list the columns explicitly, but even in this case Hibernate injects the SQL column aliases for each property. The placeholder for a column alias is just the property name qualified by the table alias. In the following example, you retrieve Cats and their mothers from a different table (cat_log) to the one declared in the mapping metadata. You can even use the property aliases in the where clause.

String sql = "SELECT ID as {c.id}, NAME as {c.name}, " +

"BIRTHDATE as {c.birthDate}, MOTHER_ID as {c.mother}, {mother.*} " + "FROM CAT_LOG c, CAT_LOG m WHERE {c.mother} = c.ID";

List loggedCats = sess.createSQLQuery(sql)

.addEntity("cat", Cat.class)

.addEntity("mother", Cat.class).list()

18.1.4.1. Alias and property references

In most cases the above alias injection is needed. For queries relating to more complex mappings, like composite properties, inheritance discriminators, collections etc., you can use specific aliases that allow Hibernate to inject the proper aliases.

The following table shows the different ways you can use the alias injection. Please note that the alias names in the result are simply examples; each alias will have a unique and probably different name when used.

Table 18.1. Alias injection names

Description

Syntax

Example

 

 

 

 

A simple property

{[aliasname].

A_NAME as {item.name}

 

 

[propertyname]

 

 

 

 

 

A

composite

{[aliasname].

CURRENCY as {item.amount.currency}, VALUE

property

 

[componentname].

as {item.amount.value}

 

 

[propertyname]}

 

 

 

 

Discriminator of an

{[aliasname].class}DISC

as {item.class}

entity

 

 

 

 

 

 

All properties of an

{[aliasname].*}

{item.*}

entity

 

 

 

 

 

 

A collection key

{[aliasname].key}

ORGID as {coll.key}

 

 

 

 

The id

of an

{[aliasname].id}

EMPID as {coll.id}

collection

 

 

 

 

 

 

300

Соседние файлы в папке more