HHH-16633 introduce new package for @HQL, @SQL, @CheckHQL annotations

This commit is contained in:
Gavin King 2023-06-17 09:58:57 +02:00
parent cfe545ec3d
commit b1998782e9
7 changed files with 141 additions and 38 deletions

View File

@ -0,0 +1,70 @@
/*
* 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.annotations.processing;
import org.hibernate.Incubating;
import org.hibernate.dialect.Dialect;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Indicates that a package or top-level type contains HQL or JPQL
* queries encoded as static strings that should be validated at
* compile time by the Hibernate Query Validator. The Query Validator
* must be enabled as an annotation processor in the project build.
* Otherwise, this annotation has no effect.
* <p>
* Within a scope annotated {@code @CheckHQL}, any static string
* argument to any one the methods:
* <ul>
* <li>{@link jakarta.persistence.EntityManager#createQuery(String,Class)},
* <li>{@link jakarta.persistence.EntityManager#createQuery(String)},
* <li>{@link org.hibernate.Session#createSelectionQuery(String,Class)}, or
* <li>{@link org.hibernate.Session#createMutationQuery(String)}
* </ul>
* or to any one of the annotation members:
* <ul>
* <li>{@link jakarta.persistence.NamedQuery#query},
* <li>{@link org.hibernate.annotations.NamedQuery#query}, or
* <li>{@link HQL#value}
* </ul>
* <p>
* is interpreted as HQL/JPQL and validated. Errors in the query are
* reported by the Java compiler.
* <p>
* The entity classes referred to in the queries must be annotated
* with basic JPA metadata annotations like {@code @Entity},
* {@code @ManyToOne}, {@code @Embeddable}, {@code @MappedSuperclass},
* {@code @ElementCollection}, and {@code @Access}. Metadata specified
* in XML mapping documents is ignored by the query validator.
* <p>
* Syntax errors, unknown entity names and unknown entity member names,
* and typing errors all result in compile-time errors.
*
* @see HQL#value()
* @see jakarta.persistence.NamedQuery#query()
* @see jakarta.persistence.EntityManager#createQuery(String,Class)
* @see org.hibernate.Session#createSelectionQuery(String,Class)
*
* @author Gavin King
*/
@Target({PACKAGE, TYPE})
@Retention(CLASS)
@Incubating
public @interface CheckHQL {
/**
* A Hibernate {@linkplain Dialect dialect} to use.
*
* @see Dialect
*/
Class<? extends Dialect> dialect() default GenericDialect.class;
}

View File

@ -0,0 +1,14 @@
/*
* 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.annotations.processing;
import org.hibernate.dialect.Dialect;
class GenericDialect extends Dialect {
GenericDialect() {
}
}

View File

@ -4,7 +4,7 @@
* 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.annotations;
package org.hibernate.annotations.processing;
import org.hibernate.Incubating;
@ -15,29 +15,27 @@ import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Identifies a method of an abstract class or interface
* as defining the signature of a method which is used to
* execute the given {@linkplain #value HQL query}, and is
* generated automatically by the Hibernate Metamodel
* Generator.
* Identifies a method of an abstract class or interface as defining
* the signature of a method which is used to execute the given
* {@linkplain #value HQL query}, and is generated automatically by
* the Hibernate Metamodel Generator.
* <p>
* For example:
* <pre>
* public interface Books {
* &#64;Hql("from Book where isbn = :isbn")
* &#64;HQL("from Book where isbn = :isbn")
* Book findBookByIsbn(String isbn);
*
* &#64;Hql("from Book where title like ?1 order by title offset ?3 fetch first ?2 rows only")
* &#64;HQL("from Book where title like ?1 order by title offset ?3 fetch first ?2 rows only")
* List&lt;Book&gt; findBooksByTitleWithPagination(String title, int max, int start);
*
* &#64;Hql("from Book where title like ?1")
* &#64;HQL("from Book where title like ?1")
* TypedQuery&lt;Book&gt; findBooksByTitle(String title);
* }
* </pre>
* <p>
* The Metamodel Generator automatically creates an
* "implementation" of these methods in the static metamodel
* class {@code Books_}.
* The Metamodel Generator automatically creates an "implementation"
* of these methods in the static metamodel class {@code Books_}.
* <pre>
* Book book = Books_.findBookByIsbn(session, isbn);
* List&lt;Book&gt; books = Books_.findBooksByTitleWithPagination(session, pattern, 10, 0);
@ -52,8 +50,8 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* <li>{@link jakarta.persistence.TypedQuery}.
* </ul>
* <p>
* The method parameters must match the parameters of the
* HQL query, either by name or by position.
* The method parameters must match the parameters of the HQL query,
* either by name or by position.
*
* @author Gavin King
* @since 6.3
@ -61,6 +59,6 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
@Target(METHOD)
@Retention(CLASS)
@Incubating
public @interface Hql {
public @interface HQL {
String value();
}

View File

@ -4,7 +4,7 @@
* 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.annotations;
package org.hibernate.annotations.processing;
import org.hibernate.Incubating;
@ -15,29 +15,27 @@ import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.CLASS;
/**
* Identifies a method of an abstract class or interface
* as defining the signature of a method which is used to
* execute the given {@linkplain #value SQL query}, and is
* generated automatically by the Hibernate Metamodel
* Generator.
* Identifies a method of an abstract class or interface as defining
* the signature of a method which is used to execute the given
* {@linkplain #value SQL query}, and is generated automatically by
* the Hibernate Metamodel Generator.
* <p>
* For example:
* <pre>
* public interface Books {
* &#64;Sql("select * from Book where isbn = :isbn")
* &#64;SQL("select * from Book where isbn = :isbn")
* Book findBookByIsbn(String isbn);
*
* &#64;Sql("select * from Book where title like ?1 order by title offset ?3 fetch first ?2 rows only")
* &#64;SQL("select * from Book where title like ?1 order by title offset ?3 fetch first ?2 rows only")
* List&lt;Book&gt; findBooksByTitleWithPagination(String title, int max, int start);
*
* &#64;Sql("select * from Book where title like ?1")
* &#64;SQL("select * from Book where title like ?1")
* Query findBooksByTitle(String title);
* }
* </pre>
* <p>
* The Metamodel Generator automatically creates an
* "implementation" of these methods in the static metamodel
* class {@code Books_}.
* The Metamodel Generator automatically creates an "implementation"
* of these methods in the static metamodel class {@code Books_}.
* <pre>
* Book book = Books_.findBookByIsbn(session, isbn);
* List&lt;Book&gt; books = Books_.findBooksByTitleWithPagination(session, pattern, 10, 0);
@ -52,8 +50,8 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* <li>{@link org.hibernate.query.NativeQuery}.
* </ul>
* <p>
* The method parameters must match the parameters of the
* SQL query, either by name or by position.
* The method parameters must match the parameters of the SQL query,
* either by name or by position.
*
* @author Gavin King
* @since 6.3
@ -61,6 +59,6 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
@Target(METHOD)
@Retention(CLASS)
@Incubating
public @interface Sql {
public @interface SQL {
String value();
}

View File

@ -0,0 +1,23 @@
/*
* 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>.
*/
/**
* Annotations used to drive annotation processors:
* <ul>
* <li>{@link org.hibernate.annotations.processing.HQL @HQL}
* and {@link org.hibernate.annotations.processing.SQL @SQL}
* are used to generate query methods using the
* Metamodel Generator, and
* <li>{@link org.hibernate.annotations.processing.CheckHQL}
* instructs the Query Validator to check all HQL queries
* in the annotated package or type.
* </ul>
*/
@Incubating
package org.hibernate.annotations.processing;
import org.hibernate.Incubating;

View File

@ -50,8 +50,8 @@ public final class Constants {
public static final String HIB_FILTER_DEF = "org.hibernate.annotations.FilterDef";
public static final String HIB_FILTER_DEFS = "org.hibernate.annotations.FilterDefs";
public static final String HQL = "org.hibernate.annotations.Hql";
public static final String SQL = "org.hibernate.annotations.Sql";
public static final String HQL = "org.hibernate.annotations.processing.HQL";
public static final String SQL = "org.hibernate.annotations.processing.SQL";
public static final Map<String, String> COLLECTIONS = allCollectionTypes();

View File

@ -1,21 +1,21 @@
package org.hibernate.jpamodelgen.test.namedquery;
import jakarta.persistence.TypedQuery;
import org.hibernate.annotations.Hql;
import org.hibernate.annotations.Sql;
import org.hibernate.annotations.processing.HQL;
import org.hibernate.annotations.processing.SQL;
import java.util.List;
public interface Dao {
@Hql("from Book where title like ?1")
@HQL("from Book where title like ?1")
TypedQuery<Book> findByTitle(String title);
@Hql("from Book where title like ?1 order by title fetch first ?2 rows only")
@HQL("from Book where title like ?1 order by title fetch first ?2 rows only")
List<Book> findFirstNByTitle(String title, int N);
@Hql("from Book where isbn = :isbn")
@HQL("from Book where isbn = :isbn")
Book findByIsbn(String isbn);
@Sql("select * from Book where isbn = :isbn")
@SQL("select * from Book where isbn = :isbn")
Book findByIsbnNative(String isbn);
}