From 3fd4fd1abee5d78acae1216027966190f511b8cf Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Wed, 17 Jul 2013 15:14:44 +0200 Subject: [PATCH] =?UTF-8?q?DATAJPA-368=20-=20Added=20documentation=20of=20?= =?UTF-8?q?SpEL=20expression=20in=20@Query(=E2=80=A6).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added appropriate sections to chapter 2. Fixed type in native query example. Updated author information on the index page. Original pull request: #26. --- src/docbkx/index.xml | 20 +++++-- src/docbkx/jpa.xml | 124 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 4 deletions(-) diff --git a/src/docbkx/index.xml b/src/docbkx/index.xml index d34d58f3d..1da12caff 100644 --- a/src/docbkx/index.xml +++ b/src/docbkx/index.xml @@ -14,12 +14,26 @@ Gierke - Senior Consultant + Software Engineer - SpringSource - a division of VMware + GoPivotal Deutschland GmbH - ogierke@vmware.com + ogierke@gopivotal.com + + + + Thomas + + Darimont + + + Software Engineer + + GoPivotal Deutschland GmbH + + + tdarimont@gopivotal.com diff --git a/src/docbkx/jpa.xml b/src/docbkx/jpa.xml index edf577990..eed83c1a8 100644 --- a/src/docbkx/jpa.xml +++ b/src/docbkx/jpa.xml @@ -549,7 +549,7 @@ public class User { public interface UserRepository extends JpaRepository<User, Long> { - @Query(value = "SELECT FROM USERS WHERE EMAIL_ADDRESS = ?0", nativeQuery = true) + @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?0", nativeQuery = true) User findByEmailAddress(String emailAddress); } @@ -580,6 +580,128 @@ public class User { +
+ Using SpEL expressions + + As of Spring Data JPA Release 1.4 we support the usage of + restricted SpEL template expressions in manually defined queries via + @Query. Upon query execution these expressions are + evaluated against a predefined set of variables. We support the + following list of variables to be used in a manual query. + + + Supported variables inside SpEL based query templates + + + + + + + + + + + Variable + + Usage + + Description + + + + + + entityName + + select x from #{#entityName} x + + Inserts the entityName of the domain type associated + with the given Repository. The entityName is + resolved as follows: If the domain type has set the name + property on the @Entity annotation then it will + be used. Otherwise the simple class-name of the domain type + will be used. + + + +
+ + The following example demonstrates one use case for the + #{#entityName} expression in a query string where you want + to define a repository interface with a query method with a manually + defined query. In order not to have to state the actual entity name in + the query string of a @Query annotation one can use the + #{#entityName} Variable. + + + Using SpEL expressions in Repository query methods - + entityName + + @Entity +public class User { + + @Id @GeneratedValue Long id; + String lastname; +} + +public interface UserRepository extends JpaRepository<User,Long> { + + @Query("select u from #{#entityName} u where u.lastname = ?1") + List<User> findByLastname(String lastname); +} + + + Of course you could have just used User in + the query declaration directly but that would require you to change the + query as well. The reference to #entityName will pick up + potential future remappings of the User class to + a different entity name (e.g. by using @Entity(name = + "MyUser"). + + Another use case for the #{#entityName} expression in + a query string is if you want to define a generic repository interface + with specialized repository interfaces for a concrete domain type. In + order not to have to repeat the definition of custom query methods on + the concrete interfaces you can use the entity name expression in the + query string of the @Query annotation in the generic + repository interface. + + + Using SpEL expressions in Repository query methods - entityName + with inheritance + + @MappedSuperclass +public abstract class AbstractMappedType { + … + String attribute +} + +@Entity +public class ConcreteType extends AbstractMappedType { … } + +@NoRepositoryBean +public interface MappedTypeRepository<T extends AbstractMappedType> + extends Repository<T, Long> { + + @Query("select t from #{#entityName} t where t.attribute = ?1") + List<T> findAllByAttribute(String attribute); +} + +public interface ConcreteRepository + extends MappedTypeRepository<ConcreteType> { … } + + + In the example the interface MappedTypeRepository is + the common parent interface for a few domain types extending + AbstractMappedType. It also defines the generic + method findAllByAttribute(…) which can be used + on instances of the specialized repository interfaces. If you now invoke + findByAllAttribute(…) on + ConcreteRepository the query being + executed will be select t from ConcreteType t where t.attribute = + ?1. +
+
Modifying queries