Migrate User Guide Native chapter extras to test folder up to stored procedures
This commit is contained in:
parent
b5a86ea45c
commit
2167b442a4
|
@ -30,6 +30,7 @@ include::chapters/portability/Portability.adoc[]
|
||||||
include::appendices/Legacy_Bootstrap.adoc[]
|
include::appendices/Legacy_Bootstrap.adoc[]
|
||||||
include::appendices/Legacy_DomainModel.adoc[]
|
include::appendices/Legacy_DomainModel.adoc[]
|
||||||
include::appendices/Legacy_Criteria.adoc[]
|
include::appendices/Legacy_Criteria.adoc[]
|
||||||
|
include::appendices/Legacy_Native_Queries.adoc[]
|
||||||
|
|
||||||
include::Bibliography.adoc[]
|
include::Bibliography.adoc[]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,375 @@
|
||||||
|
[[appendix-legacy-native-queries]]
|
||||||
|
== Legacy Hibernate Native Queries
|
||||||
|
|
||||||
|
[[legacy-sql-named-queries]]
|
||||||
|
=== Legacy Named SQL queries
|
||||||
|
|
||||||
|
Named SQL queries can also be defined during mapping and called in exactly the same way as a named HQL query.
|
||||||
|
In this case, you do _not_ need to call `addEntity()` anymore.
|
||||||
|
|
||||||
|
.Named sql query using the `<sql-query>` mapping element
|
||||||
|
====
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<sql-query name = "persons">
|
||||||
|
<return alias="person" class="eg.Person"/>
|
||||||
|
SELECT person.NAME AS {person.name},
|
||||||
|
person.AGE AS {person.age},
|
||||||
|
person.SEX AS {person.sex}
|
||||||
|
FROM PERSON person
|
||||||
|
WHERE person.NAME LIKE :namePattern
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
.Execution of a named query
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
List people = session
|
||||||
|
.getNamedQuery( "persons" )
|
||||||
|
.setString( "namePattern", namePattern )
|
||||||
|
.setMaxResults( 50 )
|
||||||
|
.list();
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
The `<return-join>` element is use to join associations and the `<load-collection>` element is used to define queries which initialize collections.
|
||||||
|
|
||||||
|
.Named sql query with association
|
||||||
|
====
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<sql-query name = "personsWith">
|
||||||
|
<return alias="person" class="eg.Person"/>
|
||||||
|
<return-join alias="address" property="person.mailingAddress"/>
|
||||||
|
SELECT person.NAME AS {person.name},
|
||||||
|
person.AGE AS {person.age},
|
||||||
|
person.SEX AS {person.sex},
|
||||||
|
address.STREET AS {address.street},
|
||||||
|
address.CITY AS {address.city},
|
||||||
|
address.STATE AS {address.state},
|
||||||
|
address.ZIP AS {address.zip}
|
||||||
|
FROM PERSON person
|
||||||
|
JOIN ADDRESS address
|
||||||
|
ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
|
||||||
|
WHERE person.NAME LIKE :namePattern
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
A named SQL query may return a scalar value.
|
||||||
|
You must declare the column alias and Hibernate type using the `<return-scalar>` element:
|
||||||
|
|
||||||
|
.Named query returning a scalar
|
||||||
|
====
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<sql-query name = "mySqlQuery">
|
||||||
|
<return-scalar column = "name" type="string"/>
|
||||||
|
<return-scalar column = "age" type="long"/>
|
||||||
|
SELECT p.NAME AS name,
|
||||||
|
p.AGE AS age,
|
||||||
|
FROM PERSON p WHERE p.NAME LIKE 'Hiber%'
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
You can externalize the resultset mapping information in a `<resultset>` element which will allow you to either reuse them across several named queries or through the `setResultSetMapping()` API.
|
||||||
|
|
||||||
|
.<resultset> mapping used to externalize mappinginformation
|
||||||
|
====
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<resultset name = "personAddress">
|
||||||
|
<return alias="person" class="eg.Person"/>
|
||||||
|
<return-join alias="address" property="person.mailingAddress"/>
|
||||||
|
</resultset>
|
||||||
|
|
||||||
|
<sql-query name = "personsWith" resultset-ref="personAddress">
|
||||||
|
SELECT person.NAME AS {person.name},
|
||||||
|
person.AGE AS {person.age},
|
||||||
|
person.SEX AS {person.sex},
|
||||||
|
address.STREET AS {address.street},
|
||||||
|
address.CITY AS {address.city},
|
||||||
|
address.STATE AS {address.state},
|
||||||
|
address.ZIP AS {address.zip}
|
||||||
|
FROM PERSON person
|
||||||
|
JOIN ADDRESS address
|
||||||
|
ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
|
||||||
|
WHERE person.NAME LIKE :namePattern
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
You can, alternatively, use the resultset mapping information in your hbm files directly in java code.
|
||||||
|
|
||||||
|
.Programmatically specifying the result mapping information
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
List cats = session
|
||||||
|
.createSQLQuery( "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id" )
|
||||||
|
.setResultSetMapping("catAndKitten")
|
||||||
|
.list();
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
[[legacy-propertyresults]]
|
||||||
|
=== Legacy return-property to explicitly specify column/alias names
|
||||||
|
|
||||||
|
You can explicitly tell Hibernate what column aliases to use with `<return-property>`, instead of using the `{}` syntax to let Hibernate inject its own aliases.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<sql-query name = "mySqlQuery">
|
||||||
|
<return alias = "person" class = "eg.Person">
|
||||||
|
<return-property name = "name" column = "myName"/>
|
||||||
|
<return-property name = "age" column = "myAge"/>
|
||||||
|
<return-property name = "sex" column = "mySex"/>
|
||||||
|
</return>
|
||||||
|
SELECT person.NAME AS myName,
|
||||||
|
person.AGE AS myAge,
|
||||||
|
person.SEX AS mySex,
|
||||||
|
FROM PERSON person WHERE person.NAME LIKE :name
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
|
||||||
|
`<return-property>` also works with multiple columns.
|
||||||
|
This solves a limitation with the `{}` syntax which cannot allow fine grained control of multi-column properties.
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<sql-query name = "organizationCurrentEmployments">
|
||||||
|
<return alias = "emp" class = "Employment">
|
||||||
|
<return-property name = "salary">
|
||||||
|
<return-column name = "VALUE"/>
|
||||||
|
<return-column name = "CURRENCY"/>
|
||||||
|
</return-property>
|
||||||
|
<return-property name = "endDate" column = "myEndDate"/>
|
||||||
|
</return>
|
||||||
|
SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer},
|
||||||
|
STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
|
||||||
|
REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCY
|
||||||
|
FROM EMPLOYMENT
|
||||||
|
WHERE EMPLOYER = :id AND ENDDATE IS NULL
|
||||||
|
ORDER BY STARTDATE ASC
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
|
||||||
|
In this example `<return-property>` was used in combination with the `{}` syntax for injection.
|
||||||
|
This allows users to choose how they want to refer column and properties.
|
||||||
|
|
||||||
|
If your mapping has a discriminator you must use `<return-discriminator>` to specify the discriminator column.
|
||||||
|
|
||||||
|
[[legacy-sp_query]]
|
||||||
|
=== Legacy stored procedures for querying
|
||||||
|
|
||||||
|
Hibernate provides support for queries via stored procedures and functions.
|
||||||
|
Most of the following documentation is equivalent for both.
|
||||||
|
The stored procedure/function must return a resultset as the first out-parameter to be able to work with Hibernate.
|
||||||
|
An example of such a stored function in Oracle 9 and higher is as follows:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
CREATE OR REPLACE FUNCTION selectAllEmployments
|
||||||
|
RETURN SYS_REFCURSOR
|
||||||
|
AS
|
||||||
|
st_cursor SYS_REFCURSOR;
|
||||||
|
BEGIN
|
||||||
|
OPEN st_cursor FOR
|
||||||
|
SELECT EMPLOYEE, EMPLOYER,
|
||||||
|
STARTDATE, ENDDATE,
|
||||||
|
REGIONCODE, EID, VALUE, CURRENCY
|
||||||
|
FROM EMPLOYMENT;
|
||||||
|
RETURN st_cursor;
|
||||||
|
END;
|
||||||
|
----
|
||||||
|
|
||||||
|
To use this query in Hibernate you need to map it via a named query.
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<sql-query name = "selectAllEmployees_SP" callable = "true">
|
||||||
|
<return alias="emp" class="Employment">
|
||||||
|
<return-property name = "employee" column = "EMPLOYEE"/>
|
||||||
|
<return-property name = "employer" column = "EMPLOYER"/>
|
||||||
|
<return-property name = "startDate" column = "STARTDATE"/>
|
||||||
|
<return-property name = "endDate" column = "ENDDATE"/>
|
||||||
|
<return-property name = "regionCode" column = "REGIONCODE"/>
|
||||||
|
<return-property name = "id" column = "EID"/>
|
||||||
|
<return-property name = "salary">
|
||||||
|
<return-column name = "VALUE"/>
|
||||||
|
<return-column name = "CURRENCY"/>
|
||||||
|
</return-property>
|
||||||
|
</return>
|
||||||
|
{ ? = call selectAllEmployments() }
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
|
||||||
|
Stored procedures currently only return scalars and entities.
|
||||||
|
`<return-join>` and `<load-collection>` are not supported.
|
||||||
|
|
||||||
|
[[legacy-sql-limits-storedprocedures]]
|
||||||
|
=== Legacy rules/limitations for using stored procedures
|
||||||
|
|
||||||
|
You cannot use stored procedures with Hibernate unless you follow some procedure/function rules.
|
||||||
|
If they do not follow those rules they are not usable with Hibernate.
|
||||||
|
If you still want to use these procedures you have to execute them via `session.doWork()`.
|
||||||
|
|
||||||
|
The rules are different for each database, since database vendors have different stored procedure semantics/syntax.
|
||||||
|
|
||||||
|
Stored procedure queries cannot be paged with `setFirstResult()/setMaxResults()`.
|
||||||
|
|
||||||
|
The recommended call form is standard SQL92: `{ ? = call functionName(<parameters>) }` or `{ ? = call procedureName(<parameters>}`.
|
||||||
|
Native call syntax is not supported.
|
||||||
|
|
||||||
|
For Oracle the following rules apply:
|
||||||
|
|
||||||
|
* A function must return a result set.
|
||||||
|
The first parameter of a procedure must be an `OUT` that returns a result set.
|
||||||
|
This is done by using a `SYS_REFCURSOR` type in Oracle 9 or 10.
|
||||||
|
In Oracle you need to define a `REF CURSOR` type.
|
||||||
|
See Oracle literature for further information.
|
||||||
|
|
||||||
|
For Sybase or MS SQL server the following rules apply:
|
||||||
|
|
||||||
|
* The procedure must return a result set.
|
||||||
|
Note that since these servers can return multiple result sets and update counts, Hibernate will iterate the results and take the first result that is a result set as its return value.
|
||||||
|
Everything else will be discarded.
|
||||||
|
* If you can enable `SET NOCOUNT ON` in your procedure it will probably be more efficient, but this is not a requirement.
|
||||||
|
|
||||||
|
[[legacy-sql-cud]]
|
||||||
|
=== Legacy custom SQL for create, update and delete
|
||||||
|
|
||||||
|
Hibernate can use custom SQL for create, update, and delete operations.
|
||||||
|
The SQL can be overridden at the statement level or individual column level.
|
||||||
|
This section describes statement overrides.
|
||||||
|
For columns, see <<chapters/domain/basic_types.adoc#mapping-column-read-and-write,Column transformers: read and write expressions>>.
|
||||||
|
The following example shows how to define custom SQL operations using annotations.
|
||||||
|
|
||||||
|
.Custom CRUD XML
|
||||||
|
====
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<class name = "Person">
|
||||||
|
<id name = "id">
|
||||||
|
<generator class = "increment"/>
|
||||||
|
</id>
|
||||||
|
<property name = "name" not-null = "true"/>
|
||||||
|
<sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert>
|
||||||
|
<sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update>
|
||||||
|
<sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
|
||||||
|
</class>
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
If you expect to call a store procedure, be sure to set the `callable` attribute to `true`, in annotations as well as in xml.
|
||||||
|
====
|
||||||
|
|
||||||
|
To check that the execution happens correctly, Hibernate allows you to define one of those three strategies:
|
||||||
|
|
||||||
|
* none: no check is performed: the store procedure is expected to fail upon issues
|
||||||
|
* count: use of rowcount to check that the update is successful
|
||||||
|
* param: like COUNT but using an output parameter rather that the standard mechanism
|
||||||
|
|
||||||
|
To define the result check style, use the `check` parameter which is again available in annotations as well as in xml.
|
||||||
|
|
||||||
|
Last but not least, stored procedures are in most cases required to return the number of rows inserted, updated and deleted.
|
||||||
|
Hibernate always registers the first statement parameter as a numeric output parameter for the CUD operations:
|
||||||
|
|
||||||
|
.Stored procedures and their return value
|
||||||
|
====
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)
|
||||||
|
RETURN NUMBER IS
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
update PERSON
|
||||||
|
set
|
||||||
|
NAME = uname,
|
||||||
|
where
|
||||||
|
ID = uid;
|
||||||
|
|
||||||
|
return SQL%ROWCOUNT;
|
||||||
|
|
||||||
|
END updatePerson;
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
[[legacy-sql-load]]
|
||||||
|
=== Legacy custom SQL for loading
|
||||||
|
|
||||||
|
You can also declare your own SQL (or HQL) queries for entity loading.
|
||||||
|
As with inserts, updates, and deletes, this can be done at the individual column level as described in
|
||||||
|
For columns, see <<chapters/domain/basic_types.adoc#mapping-column-read-and-write,Column transformers: read and write expressions>> or at the statement level.
|
||||||
|
Here is an example of a statement level override:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<sql-query name = "person">
|
||||||
|
<return alias = "pers" class = "Person" lock-mod e= "upgrade"/>
|
||||||
|
SELECT NAME AS {pers.name}, ID AS {pers.id}
|
||||||
|
FROM PERSON
|
||||||
|
WHERE ID=?
|
||||||
|
FOR UPDATE
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
|
||||||
|
This is just a named query declaration, as discussed earlier. You can reference this named query in a class mapping:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<class name = "Person">
|
||||||
|
<id name = "id">
|
||||||
|
<generator class = "increment"/>
|
||||||
|
</id>
|
||||||
|
<property name = "name" not-null = "true"/>
|
||||||
|
<loader query-ref = "person"/>
|
||||||
|
</class>
|
||||||
|
----
|
||||||
|
|
||||||
|
This even works with stored procedures.
|
||||||
|
|
||||||
|
You can even define a query for collection loading:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<set name = "employments" inverse = "true">
|
||||||
|
<key/>
|
||||||
|
<one-to-many class = "Employment"/>
|
||||||
|
<loader query-ref = "employments"/>
|
||||||
|
</set>
|
||||||
|
----
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<sql-query name = "employments">
|
||||||
|
<load-collection alias = "emp" role = "Person.employments"/>
|
||||||
|
SELECT {emp.*}
|
||||||
|
FROM EMPLOYMENT emp
|
||||||
|
WHERE EMPLOYER = :id
|
||||||
|
ORDER BY STARTDATE ASC, EMPLOYEE ASC
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
|
||||||
|
You can also define an entity loader that loads a collection by join fetching:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<sql-query name = "person">
|
||||||
|
<return alias = "pers" class = "Person"/>
|
||||||
|
<return-join alias = "emp" property = "pers.employments"/>
|
||||||
|
SELECT NAME AS {pers.*}, {emp.*}
|
||||||
|
FROM PERSON pers
|
||||||
|
LEFT OUTER JOIN EMPLOYMENT emp
|
||||||
|
ON pers.ID = emp.PERSON_ID
|
||||||
|
WHERE ID=?
|
||||||
|
</sql-query>
|
||||||
|
----
|
||||||
|
|
||||||
|
The annotation equivalent `<loader>` is the `@Loader` annotation as seen in <<example-custom-crdu-via-annotations>>.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
||||||
|
SELECT id ,
|
||||||
|
number ,
|
||||||
|
type ,
|
||||||
|
person_id
|
||||||
|
FROM phone
|
|
@ -0,0 +1,3 @@
|
||||||
|
SELECT *
|
||||||
|
FROM phone ph
|
||||||
|
JOIN call c ON c.phone_id = ph.id
|
|
@ -0,0 +1,5 @@
|
||||||
|
SELECT id ,
|
||||||
|
number ,
|
||||||
|
type ,
|
||||||
|
person_id
|
||||||
|
FROM phone
|
|
@ -0,0 +1,3 @@
|
||||||
|
SELECT *
|
||||||
|
FROM phone ph
|
||||||
|
JOIN call c ON c.phone_id = ph.id
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.model;
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.model;
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -10,7 +16,7 @@ import javax.persistence.ManyToOne;
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
//tag::hql-examples-domain-model-example[]
|
//tag::hql-examples-domain-model-example[]
|
||||||
@Entity(name = "Call")
|
@Entity
|
||||||
public class Call {
|
public class Call {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.model;
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.model;
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
@ -16,11 +22,11 @@ public class Partner {
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
@Version
|
@Version
|
||||||
private int version;
|
private int version;
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
//Getters and setters are omitted for brevity
|
//Getters and setters are omitted for brevity
|
||||||
|
|
||||||
//end::hql-examples-domain-model-example[]
|
//end::hql-examples-domain-model-example[]
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.model;
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
@ -5,6 +11,7 @@ import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Inheritance;
|
import javax.persistence.Inheritance;
|
||||||
|
import javax.persistence.InheritanceType;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +19,7 @@ import javax.persistence.ManyToOne;
|
||||||
*/
|
*/
|
||||||
//tag::hql-examples-domain-model-example[]
|
//tag::hql-examples-domain-model-example[]
|
||||||
@Entity
|
@Entity
|
||||||
@Inheritance
|
@Inheritance(strategy = InheritanceType.JOINED)
|
||||||
public class Payment {
|
public class Payment {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.model;
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -6,16 +12,24 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.ColumnResult;
|
||||||
|
import javax.persistence.ConstructorResult;
|
||||||
import javax.persistence.ElementCollection;
|
import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EntityResult;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.FieldResult;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.MapKeyEnumerated;
|
import javax.persistence.MapKeyEnumerated;
|
||||||
|
import javax.persistence.NamedNativeQueries;
|
||||||
|
import javax.persistence.NamedNativeQuery;
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.OrderColumn;
|
import javax.persistence.OrderColumn;
|
||||||
|
import javax.persistence.SqlResultSetMapping;
|
||||||
|
import javax.persistence.SqlResultSetMappings;
|
||||||
import javax.persistence.Temporal;
|
import javax.persistence.Temporal;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
import javax.persistence.Version;
|
import javax.persistence.Version;
|
||||||
|
@ -23,6 +37,115 @@ import javax.persistence.Version;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
|
@NamedNativeQueries({
|
||||||
|
//tag::sql-scalar-NamedNativeQuery-example[]
|
||||||
|
@NamedNativeQuery(
|
||||||
|
name = "find_person_name",
|
||||||
|
query =
|
||||||
|
"SELECT name " +
|
||||||
|
"FROM person "
|
||||||
|
),
|
||||||
|
//end::sql-scalar-NamedNativeQuery-example[]
|
||||||
|
//tag::sql-multiple-scalar-values-NamedNativeQuery-example[]
|
||||||
|
@NamedNativeQuery(
|
||||||
|
name = "find_person_name_and_nickName",
|
||||||
|
query =
|
||||||
|
"SELECT " +
|
||||||
|
" name, " +
|
||||||
|
" nickName " +
|
||||||
|
"FROM person "
|
||||||
|
),
|
||||||
|
//end::sql-multiple-scalar-values-NamedNativeQuery-example[]
|
||||||
|
// tag::sql-multiple-scalar-values-dto-NamedNativeQuery-example[]
|
||||||
|
@NamedNativeQuery(
|
||||||
|
name = "find_person_name_and_nickName_dto",
|
||||||
|
query =
|
||||||
|
"SELECT " +
|
||||||
|
" name, " +
|
||||||
|
" nickName " +
|
||||||
|
"FROM person ",
|
||||||
|
resultSetMapping = "name_and_nickName_dto"
|
||||||
|
),
|
||||||
|
//end::sql-multiple-scalar-values-dto-NamedNativeQuery-example[]
|
||||||
|
//tag::sql-entity-NamedNativeQuery-example[]
|
||||||
|
@NamedNativeQuery(
|
||||||
|
name = "find_person_by_name",
|
||||||
|
query =
|
||||||
|
"SELECT " +
|
||||||
|
" p.id AS \"id\", " +
|
||||||
|
" p.name AS \"name\", " +
|
||||||
|
" p.nickName AS \"nickName\", " +
|
||||||
|
" p.address AS \"address\", " +
|
||||||
|
" p.createdOn AS \"createdOn\", " +
|
||||||
|
" p.version AS \"version\" " +
|
||||||
|
"FROM person p " +
|
||||||
|
"WHERE p.name LIKE :name",
|
||||||
|
resultClass = Person.class
|
||||||
|
),
|
||||||
|
//end::sql-entity-NamedNativeQuery-example[]
|
||||||
|
//tag::sql-entity-associations-NamedNativeQuery-example[]
|
||||||
|
@NamedNativeQuery(
|
||||||
|
name = "find_person_with_phones_by_name",
|
||||||
|
query =
|
||||||
|
"SELECT " +
|
||||||
|
" pr.id AS \"pr.id\", " +
|
||||||
|
" pr.name AS \"pr.name\", " +
|
||||||
|
" pr.nickName AS \"pr.nickName\", " +
|
||||||
|
" pr.address AS \"pr.address\", " +
|
||||||
|
" pr.createdOn AS \"pr.createdOn\", " +
|
||||||
|
" pr.version AS \"pr.version\", " +
|
||||||
|
" ph.id AS \"ph.id\", " +
|
||||||
|
" ph.person_id AS \"ph.person_id\", " +
|
||||||
|
" ph.number AS \"ph.number\", " +
|
||||||
|
" ph.type AS \"ph.type\" " +
|
||||||
|
"FROM person pr " +
|
||||||
|
"JOIN phone ph ON pr.id = ph.person_id " +
|
||||||
|
"WHERE pr.name LIKE :name",
|
||||||
|
resultSetMapping = "person_with_phones"
|
||||||
|
)
|
||||||
|
//end::sql-entity-associations-NamedNativeQuery-example[]
|
||||||
|
})
|
||||||
|
@SqlResultSetMappings({
|
||||||
|
//tag::sql-entity-associations-NamedNativeQuery-example[]
|
||||||
|
@SqlResultSetMapping(
|
||||||
|
name = "person_with_phones",
|
||||||
|
entities = {
|
||||||
|
@EntityResult(
|
||||||
|
entityClass = Person.class,
|
||||||
|
fields = {
|
||||||
|
@FieldResult( name = "id", column = "pr.id" ),
|
||||||
|
@FieldResult( name = "name", column = "pr.name" ),
|
||||||
|
@FieldResult( name = "nickName", column = "pr.nickName" ),
|
||||||
|
@FieldResult( name = "address", column = "pr.address" ),
|
||||||
|
@FieldResult( name = "createdOn", column = "pr.createdOn" ),
|
||||||
|
@FieldResult( name = "version", column = "pr.version" ),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
@EntityResult(
|
||||||
|
entityClass = Phone.class,
|
||||||
|
fields = {
|
||||||
|
@FieldResult( name = "id", column = "ph.id" ),
|
||||||
|
@FieldResult( name = "person", column = "ph.person_id" ),
|
||||||
|
@FieldResult( name = "number", column = "ph.number" ),
|
||||||
|
@FieldResult( name = "type", column = "ph.type" ),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
//end::sql-entity-associations-NamedNativeQuery-example[]
|
||||||
|
//tag::sql-multiple-scalar-values-dto-NamedNativeQuery-example[]
|
||||||
|
@SqlResultSetMapping(
|
||||||
|
name = "name_and_nickName_dto",
|
||||||
|
classes = @ConstructorResult(
|
||||||
|
targetClass = PersonNames.class,
|
||||||
|
columns = {
|
||||||
|
@ColumnResult(name = "name"),
|
||||||
|
@ColumnResult(name = "nickName")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
//end::sql-multiple-scalar-values-dto-NamedNativeQuery-example[]
|
||||||
|
})
|
||||||
//tag::hql-examples-domain-model-example[]
|
//tag::hql-examples-domain-model-example[]
|
||||||
//tag::jpql-api-named-query-example[]
|
//tag::jpql-api-named-query-example[]
|
||||||
@NamedQueries(
|
@NamedQueries(
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
//tag::sql-ConstructorResult-dto-example[]
|
||||||
|
public class PersonNames {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private final String nickName;
|
||||||
|
|
||||||
|
public PersonNames(String name, String nickName) {
|
||||||
|
this.name = name;
|
||||||
|
this.nickName = nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickName() {
|
||||||
|
return nickName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end::sql-ConstructorResult-dto-example[]
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.model;
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -10,6 +16,7 @@ import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.MapKey;
|
import javax.persistence.MapKey;
|
||||||
|
@ -27,7 +34,7 @@ public class Phone {
|
||||||
@Id
|
@Id
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
private Person person;
|
private Person person;
|
||||||
|
|
||||||
private String number;
|
private String number;
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.model;
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.model;
|
package org.hibernate.userguide.model;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.criteria;
|
package org.hibernate.userguide.criteria;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.hql;
|
package org.hibernate.userguide.hql;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.locking;
|
package org.hibernate.userguide.locking;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.locking;
|
package org.hibernate.userguide.locking;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
package org.hibernate.userguide.sql;
|
||||||
|
import javax.persistence.EmbeddedId;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
* @author Vlad MIhalcea
|
||||||
|
*/
|
||||||
|
//tag::sql-composite-key-entity-associations_named-query-example[]
|
||||||
|
@Entity
|
||||||
|
public class Captain {
|
||||||
|
|
||||||
|
@EmbeddedId
|
||||||
|
private Identity id;
|
||||||
|
|
||||||
|
public Identity getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Identity id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end::sql-composite-key-entity-associations_named-query-example[]
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
package org.hibernate.userguide.sql;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
* @author Vlad MIhalcea
|
||||||
|
*/
|
||||||
|
//tag::sql-composite-key-entity-associations_named-query-example[]
|
||||||
|
@Embeddable
|
||||||
|
public class Dimensions {
|
||||||
|
|
||||||
|
private int length;
|
||||||
|
|
||||||
|
private int width;
|
||||||
|
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLength(int length) {
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(int width) {
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end::sql-composite-key-entity-associations_named-query-example[]
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
package org.hibernate.userguide.sql;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
* @author Vlad MIhalcea
|
||||||
|
*/
|
||||||
|
//tag::sql-composite-key-entity-associations_named-query-example[]
|
||||||
|
@Embeddable
|
||||||
|
public class Identity implements Serializable {
|
||||||
|
|
||||||
|
private String firstname;
|
||||||
|
|
||||||
|
private String lastname;
|
||||||
|
|
||||||
|
public String getFirstname() {
|
||||||
|
return firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstname(String firstname) {
|
||||||
|
this.firstname = firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastname() {
|
||||||
|
return lastname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastname(String lastname) {
|
||||||
|
this.lastname = lastname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) return true;
|
||||||
|
if ( o == null || getClass() != o.getClass() ) return false;
|
||||||
|
|
||||||
|
final Identity identity = (Identity) o;
|
||||||
|
|
||||||
|
if ( !firstname.equals( identity.firstname ) ) return false;
|
||||||
|
if ( !lastname.equals( identity.lastname ) ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
int result;
|
||||||
|
result = firstname.hashCode();
|
||||||
|
result = 29 * result + lastname.hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end::sql-composite-key-entity-associations_named-query-example[]
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.userguide.sql;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
//tag::sql-hibernate-dto-query-example[]
|
||||||
|
public class PersonSummaryDTO {
|
||||||
|
|
||||||
|
private BigInteger id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public BigInteger getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(BigInteger id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-dto-query-example[]
|
|
@ -0,0 +1,761 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.userguide.sql;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
|
import org.hibernate.Criteria;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
import org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException;
|
||||||
|
import org.hibernate.transform.Transformers;
|
||||||
|
import org.hibernate.type.LongType;
|
||||||
|
import org.hibernate.type.StringType;
|
||||||
|
import org.hibernate.userguide.model.AddressType;
|
||||||
|
import org.hibernate.userguide.model.Call;
|
||||||
|
import org.hibernate.userguide.model.CreditCardPayment;
|
||||||
|
import org.hibernate.userguide.model.Partner;
|
||||||
|
import org.hibernate.userguide.model.Person;
|
||||||
|
import org.hibernate.userguide.model.PersonNames;
|
||||||
|
import org.hibernate.userguide.model.Phone;
|
||||||
|
import org.hibernate.userguide.model.PhoneType;
|
||||||
|
import org.hibernate.userguide.model.WireTransferPayment;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import static org.hibernate.userguide.util.TransactionUtil.doInJPA;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
public class SQLTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger( SQLTest.class );
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] {
|
||||||
|
Person.class,
|
||||||
|
Partner.class,
|
||||||
|
Phone.class,
|
||||||
|
Call.class,
|
||||||
|
CreditCardPayment.class,
|
||||||
|
WireTransferPayment.class,
|
||||||
|
SpaceShip.class,
|
||||||
|
Captain.class,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Person person1 = new Person("John Doe" );
|
||||||
|
person1.setNickName( "JD" );
|
||||||
|
person1.setAddress( "Earth" );
|
||||||
|
person1.setCreatedOn( Timestamp.from( LocalDateTime.of( 2000, 1, 1, 0, 0, 0 ).toInstant( ZoneOffset.UTC ) )) ;
|
||||||
|
person1.getAddresses().put( AddressType.HOME, "Home address" );
|
||||||
|
person1.getAddresses().put( AddressType.OFFICE, "Office address" );
|
||||||
|
entityManager.persist(person1);
|
||||||
|
|
||||||
|
Person person2 = new Person("Mrs. John Doe" );
|
||||||
|
person2.setAddress( "Earth" );
|
||||||
|
person2.setCreatedOn( Timestamp.from( LocalDateTime.of( 2000, 1, 2, 12, 0, 0 ).toInstant( ZoneOffset.UTC ) )) ;
|
||||||
|
entityManager.persist(person2);
|
||||||
|
|
||||||
|
Person person3 = new Person("Dr_ John Doe" );
|
||||||
|
entityManager.persist(person3);
|
||||||
|
|
||||||
|
Phone phone1 = new Phone( "123-456-7890" );
|
||||||
|
phone1.setId( 1L );
|
||||||
|
phone1.setType( PhoneType.MOBILE );
|
||||||
|
person1.addPhone( phone1 );
|
||||||
|
phone1.getRepairTimestamps().add( Timestamp.from( LocalDateTime.of( 2005, 1, 1, 12, 0, 0 ).toInstant( ZoneOffset.UTC ) ) );
|
||||||
|
phone1.getRepairTimestamps().add( Timestamp.from( LocalDateTime.of( 2006, 1, 1, 12, 0, 0 ).toInstant( ZoneOffset.UTC ) ) );
|
||||||
|
|
||||||
|
Call call11 = new Call();
|
||||||
|
call11.setDuration( 12 );
|
||||||
|
call11.setTimestamp( Timestamp.from( LocalDateTime.of( 2000, 1, 1, 0, 0, 0 ).toInstant( ZoneOffset.UTC ) ) );
|
||||||
|
|
||||||
|
Call call12 = new Call();
|
||||||
|
call12.setDuration( 33 );
|
||||||
|
call12.setTimestamp( Timestamp.from( LocalDateTime.of( 2000, 1, 1, 1, 0, 0 ).toInstant( ZoneOffset.UTC ) ) );
|
||||||
|
|
||||||
|
phone1.addCall(call11);
|
||||||
|
phone1.addCall(call12);
|
||||||
|
|
||||||
|
Phone phone2 = new Phone( "098_765-4321" );
|
||||||
|
phone2.setId( 2L );
|
||||||
|
phone2.setType( PhoneType.LAND_LINE );
|
||||||
|
|
||||||
|
Phone phone3 = new Phone( "098-765-4320" );
|
||||||
|
phone3.setId( 3L );
|
||||||
|
phone3.setType( PhoneType.LAND_LINE );
|
||||||
|
|
||||||
|
person2.addPhone( phone2 );
|
||||||
|
person2.addPhone( phone3 );
|
||||||
|
|
||||||
|
CreditCardPayment creditCardPayment = new CreditCardPayment();
|
||||||
|
creditCardPayment.setCompleted( true );
|
||||||
|
creditCardPayment.setAmount( BigDecimal.ZERO );
|
||||||
|
creditCardPayment.setPerson( person1 );
|
||||||
|
|
||||||
|
WireTransferPayment wireTransferPayment = new WireTransferPayment();
|
||||||
|
wireTransferPayment.setCompleted( true );
|
||||||
|
wireTransferPayment.setAmount( BigDecimal.valueOf( 100 ) );
|
||||||
|
wireTransferPayment.setPerson( person2 );
|
||||||
|
|
||||||
|
entityManager.persist( creditCardPayment );
|
||||||
|
entityManager.persist( wireTransferPayment );
|
||||||
|
|
||||||
|
Partner partner = new Partner( "John Doe" );
|
||||||
|
entityManager.persist( partner );
|
||||||
|
|
||||||
|
Captain captain = new Captain();
|
||||||
|
captain.setId( new Identity() );
|
||||||
|
captain.getId().setFirstname( "Jean-Luc" );
|
||||||
|
captain.getId().setLastname( "Picard" );
|
||||||
|
|
||||||
|
entityManager.persist( captain );
|
||||||
|
|
||||||
|
SpaceShip spaceShip = new SpaceShip();
|
||||||
|
spaceShip.setName( "Enterprise" );
|
||||||
|
spaceShip.setDimensions( new Dimensions() );
|
||||||
|
spaceShip.getDimensions().setLength( 100 );
|
||||||
|
spaceShip.getDimensions().setWidth( 20 );
|
||||||
|
spaceShip.setModel( "E-1" );
|
||||||
|
spaceShip.setSpeed( 150 );
|
||||||
|
spaceShip.setCaptain( captain );
|
||||||
|
entityManager.persist( spaceShip );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_all_columns_scalar_query_example() {
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-all-columns-scalar-query-example[]
|
||||||
|
List<Object[]> persons = entityManager.createNativeQuery(
|
||||||
|
"SELECT * FROM person" )
|
||||||
|
.getResultList();
|
||||||
|
//end::sql-jpa-all-columns-scalar-query-example[]
|
||||||
|
assertEquals( 3, persons.size() );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_custom_column_selection_scalar_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-custom-column-selection-scalar-query-example[]
|
||||||
|
List<Object[]> persons = entityManager.createNativeQuery(
|
||||||
|
"SELECT id, name FROM person" )
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
for(Object[] person : persons) {
|
||||||
|
BigInteger id = (BigInteger) person[0];
|
||||||
|
String name = (String) person[1];
|
||||||
|
}
|
||||||
|
//end::sql-jpa-custom-column-selection-scalar-query-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_query_scalar_example() {
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-all-columns-scalar-query-example[]
|
||||||
|
List<Object[]> persons = session.createSQLQuery(
|
||||||
|
"SELECT * FROM person" )
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-all-columns-scalar-query-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_custom_column_selection_scalar_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-custom-column-selection-scalar-query-example[]
|
||||||
|
List<Object[]> persons = session.createSQLQuery(
|
||||||
|
"SELECT id, name FROM person" )
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Object[] person : persons) {
|
||||||
|
BigInteger id = (BigInteger) person[0];
|
||||||
|
String name = (String) person[1];
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-custom-column-selection-scalar-query-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_query_scalar_explicit_result_set_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-scalar-query-explicit-result-set-example[]
|
||||||
|
List<Object[]> persons = session.createSQLQuery(
|
||||||
|
"SELECT * FROM person" )
|
||||||
|
.addScalar( "id", LongType.INSTANCE )
|
||||||
|
.addScalar( "name", StringType.INSTANCE )
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Object[] person : persons) {
|
||||||
|
Long id = (Long) person[0];
|
||||||
|
String name = (String) person[1];
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-scalar-query-explicit-result-set-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_query_scalar_partial_explicit_result_set_example() {
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-scalar-query-partial-explicit-result-set-example[]
|
||||||
|
List<Object[]> persons = session.createSQLQuery(
|
||||||
|
"SELECT * FROM person" )
|
||||||
|
.addScalar( "id", LongType.INSTANCE )
|
||||||
|
.addScalar( "name" )
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Object[] person : persons) {
|
||||||
|
Long id = (Long) person[0];
|
||||||
|
String name = (String) person[1];
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-scalar-query-partial-explicit-result-set-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_entity_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-entity-query-example[]
|
||||||
|
List<Person> persons = entityManager.createNativeQuery(
|
||||||
|
"SELECT * FROM person", Person.class )
|
||||||
|
.getResultList();
|
||||||
|
//end::sql-jpa-entity-query-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_entity_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-entity-query-example[]
|
||||||
|
List<Person> persons = session.createSQLQuery(
|
||||||
|
"SELECT * FROM person" )
|
||||||
|
.addEntity( Person.class )
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-entity-query-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_entity_query_explicit_result_set_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-entity-query-explicit-result-set-example[]
|
||||||
|
List<Person> persons = entityManager.createNativeQuery(
|
||||||
|
"SELECT id, name, nickName, address, createdOn, version " +
|
||||||
|
"FROM person", Person.class )
|
||||||
|
.getResultList();
|
||||||
|
//end::sql-jpa-entity-query-explicit-result-set-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_entity_query_explicit_result_set_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-entity-query-explicit-result-set-example[]
|
||||||
|
List<Person> persons = session.createSQLQuery(
|
||||||
|
"SELECT id, name, nickName, address, createdOn, version " +
|
||||||
|
"FROM person" )
|
||||||
|
.addEntity( Person.class )
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-entity-query-explicit-result-set-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_entity_associations_query_many_to_one_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-entity-associations-query-many-to-one-example[]
|
||||||
|
List<Phone> phones = entityManager.createNativeQuery(
|
||||||
|
"SELECT id, number, type, person_id " +
|
||||||
|
"FROM phone", Phone.class )
|
||||||
|
.getResultList();
|
||||||
|
//end::sql-jpa-entity-associations-query-many-to-one-example[]
|
||||||
|
assertEquals(3, phones.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_entity_associations_query_many_to_one_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-entity-associations-query-many-to-one-example[]
|
||||||
|
List<Phone> phones = session.createSQLQuery(
|
||||||
|
"SELECT id, number, type, person_id " +
|
||||||
|
"FROM phone" )
|
||||||
|
.addEntity( Phone.class )
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-entity-associations-query-many-to-one-example[]
|
||||||
|
assertEquals(3, phones.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_entity_associations_query_many_to_one_join_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-entity-associations-query-many-to-one-join-example[]
|
||||||
|
List<Phone> phones = entityManager.createNativeQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM phone ph " +
|
||||||
|
"JOIN person pr ON ph.person_id = pr.id", Phone.class )
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
for(Phone phone : phones) {
|
||||||
|
Person person = phone.getPerson();
|
||||||
|
}
|
||||||
|
//end::sql-jpa-entity-associations-query-many-to-one-join-example[]
|
||||||
|
assertEquals(3, phones.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_entity_associations_query_many_to_one_join_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-entity-associations-query-many-to-one-join-example[]
|
||||||
|
List<Object[]> tuples = session.createSQLQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM phone ph " +
|
||||||
|
"JOIN person pr ON ph.person_id = pr.id" )
|
||||||
|
.addEntity("phone", Phone.class )
|
||||||
|
.addJoin( "pr", "phone.person")
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Object[] tuple : tuples) {
|
||||||
|
Phone phone = (Phone) tuple[0];
|
||||||
|
Person person = (Person) tuple[1];
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-entity-associations-query-many-to-one-join-example[]
|
||||||
|
assertEquals(3, tuples.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_entity_associations_query_many_to_one_join_result_transformer_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-entity-associations-query-many-to-one-join-result-transformer-example[]
|
||||||
|
List<Person> persons = session.createSQLQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM phone ph " +
|
||||||
|
"JOIN person pr ON ph.person_id = pr.id" )
|
||||||
|
.addEntity("phone", Phone.class )
|
||||||
|
.addJoin( "pr", "phone.person")
|
||||||
|
.setResultTransformer( Criteria.ROOT_ENTITY )
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Person person : persons) {
|
||||||
|
person.getPhones();
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-entity-associations-query-many-to-one-join-result-transformer-example[]
|
||||||
|
assertEquals(3, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_entity_associations_query_one_to_many_join_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-entity-associations-query-one-to-many-join-example[]
|
||||||
|
List<Phone> phones = entityManager.createNativeQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM phone ph " +
|
||||||
|
"JOIN call c ON c.phone_id = ph.id", Phone.class )
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
for(Phone phone : phones) {
|
||||||
|
List<Call> calls = phone.getCalls();
|
||||||
|
}
|
||||||
|
//end::sql-jpa-entity-associations-query-one-to-many-join-example[]
|
||||||
|
assertEquals(2, phones.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_entity_associations_query_one_to_many_join_example_1() {
|
||||||
|
try {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
List<Phone> phones = session.createSQLQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM phone ph " +
|
||||||
|
"JOIN call c ON c.phone_id = ph.id" )
|
||||||
|
.addEntity("phone", Phone.class )
|
||||||
|
.addJoin( "c", "phone.calls")
|
||||||
|
.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY )
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Phone phone : phones) {
|
||||||
|
List<Call> calls = phone.getCalls();
|
||||||
|
}
|
||||||
|
assertEquals(2, phones.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.error( "HHH-10504", e );
|
||||||
|
//See issue https://hibernate.atlassian.net/browse/HHH-10504
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_entity_associations_query_one_to_many_join_example_2() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-entity-associations-query-one-to-many-join-example[]
|
||||||
|
List<Object[]> tuples = session.createSQLQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM phone ph " +
|
||||||
|
"JOIN call c ON c.phone_id = ph.id" )
|
||||||
|
.addEntity("phone", Phone.class )
|
||||||
|
.addJoin( "c", "phone.calls")
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Object[] tuple : tuples) {
|
||||||
|
Phone phone = (Phone) tuple[0];
|
||||||
|
Call call = (Call) tuple[1];
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-entity-associations-query-one-to-many-join-example[]
|
||||||
|
assertEquals(2, tuples.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_multi_entity_query_example() {
|
||||||
|
try {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-multi-entity-query-example[]
|
||||||
|
List<Object> entities = entityManager.createNativeQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM person pr, partner pt " +
|
||||||
|
"WHERE pr.name = pt.name" )
|
||||||
|
.getResultList();
|
||||||
|
//end::sql-jpa-multi-entity-query-example[]
|
||||||
|
assertEquals(2, entities.size());
|
||||||
|
});
|
||||||
|
fail("Should throw NonUniqueDiscoveredSqlAliasException!");
|
||||||
|
}
|
||||||
|
catch (PersistenceException expected) {
|
||||||
|
assertEquals( NonUniqueDiscoveredSqlAliasException.class, expected.getCause().getClass() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NonUniqueDiscoveredSqlAliasException.class)
|
||||||
|
public void test_sql_hibernate_multi_entity_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-multi-entity-query-example[]
|
||||||
|
List<Object> entities = session.createSQLQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM person pr, partner pt " +
|
||||||
|
"WHERE pr.name = pt.name" )
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-multi-entity-query-example[]
|
||||||
|
assertEquals(2, entities.size());
|
||||||
|
});
|
||||||
|
fail("Should throw NonUniqueDiscoveredSqlAliasException!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_multi_entity_query_alias_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-multi-entity-query-alias-example[]
|
||||||
|
List<Object> entities = session.createSQLQuery(
|
||||||
|
"SELECT {pr.*}, {pt.*} " +
|
||||||
|
"FROM person pr, partner pt " +
|
||||||
|
"WHERE pr.name = pt.name" )
|
||||||
|
.addEntity( "pr", Person.class)
|
||||||
|
.addEntity( "pt", Partner.class)
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-multi-entity-query-alias-example[]
|
||||||
|
assertEquals(1, entities.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_dto_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-dto-query-example[]
|
||||||
|
List<PersonSummaryDTO> dtos = session.createSQLQuery(
|
||||||
|
"SELECT p.id as \"id\", p.name as \"name\" " +
|
||||||
|
"FROM person p")
|
||||||
|
.setResultTransformer( Transformers.aliasToBean( PersonSummaryDTO.class ) )
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-dto-query-example[]
|
||||||
|
assertEquals(3, dtos.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_inheritance_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-inheritance-query-example[]
|
||||||
|
List<CreditCardPayment> payments = session.createSQLQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM Payment p " +
|
||||||
|
"JOIN CreditCardPayment cp on cp.id = p.id" )
|
||||||
|
.addEntity( CreditCardPayment.class )
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-inheritance-query-example[]
|
||||||
|
assertEquals(1, payments.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_query_parameters_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-query-parameters-example[]
|
||||||
|
List<Person> persons = entityManager.createNativeQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM person " +
|
||||||
|
"WHERE name like :name", Person.class )
|
||||||
|
.setParameter("name", "J%")
|
||||||
|
.getResultList();
|
||||||
|
//end::sql-jpa-query-parameters-example[]
|
||||||
|
assertEquals(1, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_query_parameters_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-query-parameters-example[]
|
||||||
|
List<Person> persons = session.createSQLQuery(
|
||||||
|
"SELECT * " +
|
||||||
|
"FROM person " +
|
||||||
|
"WHERE name like :name" )
|
||||||
|
.addEntity( Person.class )
|
||||||
|
.setParameter("name", "J%")
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-query-parameters-example[]
|
||||||
|
assertEquals(1, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_scalar_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-scalar-named-query-example[]
|
||||||
|
List<String> names = entityManager.createNamedQuery(
|
||||||
|
"find_person_name" )
|
||||||
|
.getResultList();
|
||||||
|
//end::sql-jpa-scalar-named-query-example[]
|
||||||
|
assertEquals(3, names.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_scalar_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-scalar-named-query-example[]
|
||||||
|
List<String> names = session.getNamedQuery(
|
||||||
|
"find_person_name" )
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-scalar-named-query-example[]
|
||||||
|
assertEquals(3, names.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_multiple_scalar_values_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-multiple-scalar-values-named-query-example[]
|
||||||
|
List<Object[]> tuples = entityManager.createNamedQuery(
|
||||||
|
"find_person_name_and_nickName" )
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
for(Object[] tuple : tuples) {
|
||||||
|
String name = (String) tuple[0];
|
||||||
|
String nickName = (String) tuple[1];
|
||||||
|
}
|
||||||
|
//end::sql-jpa-multiple-scalar-values-named-query-example[]
|
||||||
|
assertEquals(3, tuples.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_multiple_scalar_values_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-multiple-scalar-values-named-query-example[]
|
||||||
|
List<Object[]> tuples = session.getNamedQuery(
|
||||||
|
"find_person_name_and_nickName" )
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Object[] tuple : tuples) {
|
||||||
|
String name = (String) tuple[0];
|
||||||
|
String nickName = (String) tuple[1];
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-multiple-scalar-values-named-query-example[]
|
||||||
|
assertEquals(3, tuples.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_multiple_scalar_values_dto_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-multiple-scalar-values-dto-named-query-example[]
|
||||||
|
List<PersonNames> personNames = entityManager.createNamedQuery(
|
||||||
|
"find_person_name_and_nickName_dto" )
|
||||||
|
.getResultList();
|
||||||
|
//end::sql-jpa-multiple-scalar-values-dto-named-query-example[]
|
||||||
|
assertEquals(3, personNames.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_multiple_scalar_values_dto_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-multiple-scalar-values-dto-named-query-example[]
|
||||||
|
List<PersonNames> personNames = session.getNamedQuery(
|
||||||
|
"find_person_name_and_nickName_dto" )
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-multiple-scalar-values-dto-named-query-example[]
|
||||||
|
assertEquals(3, personNames.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_entity_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-entity-named-query-example[]
|
||||||
|
List<Person> persons = entityManager.createNamedQuery(
|
||||||
|
"find_person_by_name" )
|
||||||
|
.setParameter("name", "J%")
|
||||||
|
.getResultList();
|
||||||
|
//end::sql-jpa-entity-named-query-example[]
|
||||||
|
assertEquals(1, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_entity_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-entity-named-query-example[]
|
||||||
|
List<Person> persons = session.getNamedQuery(
|
||||||
|
"find_person_by_name" )
|
||||||
|
.setParameter("name", "J%")
|
||||||
|
.list();
|
||||||
|
//end::sql-hibernate-entity-named-query-example[]
|
||||||
|
assertEquals(1, persons.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_entity_associations_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-entity-associations_named-query-example[]
|
||||||
|
List<Object[]> tuples = entityManager.createNamedQuery(
|
||||||
|
"find_person_with_phones_by_name" )
|
||||||
|
.setParameter("name", "J%")
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
for(Object[] tuple : tuples) {
|
||||||
|
Person person = (Person) tuple[0];
|
||||||
|
Phone phone = (Phone) tuple[1];
|
||||||
|
}
|
||||||
|
//end::sql-jpa-entity-associations_named-query-example[]
|
||||||
|
assertEquals(1, tuples.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_entity_associations_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-entity-associations_named-query-example[]
|
||||||
|
List<Object[]> tuples = session.getNamedQuery(
|
||||||
|
"find_person_with_phones_by_name" )
|
||||||
|
.setParameter("name", "J%")
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Object[] tuple : tuples) {
|
||||||
|
Person person = (Person) tuple[0];
|
||||||
|
Phone phone = (Phone) tuple[1];
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-entity-associations_named-query-example[]
|
||||||
|
assertEquals(1, tuples.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_jpa_composite_key_entity_associations_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
//tag::sql-jpa-composite-key-entity-associations_named-query-example[]
|
||||||
|
List<Object[]> tuples = entityManager.createNamedQuery(
|
||||||
|
"find_all_spaceships" )
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
for(Object[] tuple : tuples) {
|
||||||
|
SpaceShip spaceShip = (SpaceShip) tuple[0];
|
||||||
|
Integer surface = (Integer) tuple[1];
|
||||||
|
Integer volume = (Integer) tuple[2];
|
||||||
|
}
|
||||||
|
//end::sql-jpa-composite-key-entity-associations_named-query-example[]
|
||||||
|
assertEquals(1, tuples.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_sql_hibernate_composite_key_entity_associations_named_query_example() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Session session = entityManager.unwrap( Session.class );
|
||||||
|
//tag::sql-hibernate-composite-key-entity-associations_named-query-example[]
|
||||||
|
List<Object[]> tuples = session.getNamedQuery(
|
||||||
|
"find_all_spaceships" )
|
||||||
|
.list();
|
||||||
|
|
||||||
|
for(Object[] tuple : tuples) {
|
||||||
|
SpaceShip spaceShip = (SpaceShip) tuple[0];
|
||||||
|
Integer surface = (Integer) tuple[1];
|
||||||
|
Integer volume = (Integer) tuple[2];
|
||||||
|
}
|
||||||
|
//end::sql-hibernate-composite-key-entity-associations_named-query-example[]
|
||||||
|
assertEquals(1, tuples.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
package org.hibernate.userguide.sql;
|
||||||
|
|
||||||
|
import javax.persistence.ColumnResult;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EntityResult;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.FieldResult;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinColumns;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.NamedNativeQueries;
|
||||||
|
import javax.persistence.NamedNativeQuery;
|
||||||
|
import javax.persistence.SqlResultSetMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
* @author Vlad MIhalcea
|
||||||
|
*/
|
||||||
|
//tag::sql-composite-key-entity-associations_named-query-example[]
|
||||||
|
@Entity
|
||||||
|
@NamedNativeQueries({
|
||||||
|
@NamedNativeQuery(name = "find_all_spaceships",
|
||||||
|
query =
|
||||||
|
"SELECT " +
|
||||||
|
" name as \"name\", " +
|
||||||
|
" model, " +
|
||||||
|
" speed, " +
|
||||||
|
" lname as lastn, " +
|
||||||
|
" fname as firstn, " +
|
||||||
|
" length, " +
|
||||||
|
" width, " +
|
||||||
|
" length * width as surface, " +
|
||||||
|
" length * width * 10 as volume " +
|
||||||
|
"FROM SpaceShip",
|
||||||
|
resultSetMapping = "spaceship"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
@SqlResultSetMapping(
|
||||||
|
name = "spaceship",
|
||||||
|
entities = @EntityResult(
|
||||||
|
entityClass = SpaceShip.class,
|
||||||
|
fields = {
|
||||||
|
@FieldResult(name = "name", column = "name"),
|
||||||
|
@FieldResult(name = "model", column = "model"),
|
||||||
|
@FieldResult(name = "speed", column = "speed"),
|
||||||
|
@FieldResult(name = "captain.lastname", column = "lastn"),
|
||||||
|
@FieldResult(name = "captain.firstname", column = "firstn"),
|
||||||
|
@FieldResult(name = "dimensions.length", column = "length"),
|
||||||
|
@FieldResult(name = "dimensions.width", column = "width"),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
columns = {
|
||||||
|
@ColumnResult(name = "surface"),
|
||||||
|
@ColumnResult(name = "volume")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public class SpaceShip {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String model;
|
||||||
|
|
||||||
|
private double speed;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumns({
|
||||||
|
@JoinColumn(name = "fname", referencedColumnName = "firstname"),
|
||||||
|
@JoinColumn(name = "lname", referencedColumnName = "lastname")
|
||||||
|
})
|
||||||
|
private Captain captain;
|
||||||
|
|
||||||
|
private Dimensions dimensions;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModel() {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModel(String model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpeed(double speed) {
|
||||||
|
this.speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Captain getCaptain() {
|
||||||
|
return captain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCaptain(Captain captain) {
|
||||||
|
this.captain = captain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dimensions getDimensions() {
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDimensions(Dimensions dimensions) {
|
||||||
|
this.dimensions = dimensions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end::sql-composite-key-entity-associations_named-query-example[]
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
package org.hibernate.userguide.transactions;
|
package org.hibernate.userguide.transactions;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|
|
@ -25,8 +25,7 @@ log4j.logger.org.hibernate.reflection=info
|
||||||
log4j.logger.org.hibernate.SQL=debug
|
log4j.logger.org.hibernate.SQL=debug
|
||||||
|
|
||||||
### log JDBC bind parameters ###
|
### log JDBC bind parameters ###
|
||||||
#log4j.logger.org.hibernate.type=info
|
log4j.logger.org.hibernate.type=info
|
||||||
log4j.logger.org.hibernate.type=trace
|
|
||||||
|
|
||||||
### log schema export/update ###
|
### log schema export/update ###
|
||||||
log4j.logger.org.hibernate.tool.hbm2ddl=info
|
log4j.logger.org.hibernate.tool.hbm2ddl=info
|
||||||
|
|
Loading…
Reference in New Issue