diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/processing/CheckHQL.java b/hibernate-core/src/main/java/org/hibernate/annotations/processing/CheckHQL.java index a6e94c77eb..153b81fcc8 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/processing/CheckHQL.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/processing/CheckHQL.java @@ -57,7 +57,24 @@ import static java.lang.annotation.RetentionPolicy.CLASS; * @see jakarta.persistence.EntityManager#createQuery(String,Class) * @see org.hibernate.Session#createSelectionQuery(String,Class) * + * @implNote The static HQL type checker is not aware of metadata defined + * purely in XML, nor of JPA converters, and therefore sometimes + * reports false positives. That is, it rejects queries at compile + * time that would be accepted at runtime. + *

+ * Therefore, by default, HQL specified in {@code NamedQuery} + * annotations is always validated for both syntax and semantics, + * but only illegal syntax is reported with severity + * {@link javax.tools.Diagnostic.Kind#ERROR}. Problems with the + * semantics of HQL named queries (typing problem) are reported to + * the Java compiler by the Metamodel Generator with severity + * {@link javax.tools.Diagnostic.Kind#WARNING}. + *

+ * So, actually, the effect of {@code CheckHQL} is only to change + * the severity of reported problem. + * * @author Gavin King + * @since 6.3 */ @Target({PACKAGE, TYPE}) @Retention(CLASS) diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/processing/Find.java b/hibernate-core/src/main/java/org/hibernate/annotations/processing/Find.java index 9035f7d91c..5ad6b6255e 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/processing/Find.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/processing/Find.java @@ -16,10 +16,20 @@ import static java.lang.annotation.RetentionPolicy.CLASS; /** * Identifies a method of an abstract class or interface as defining - * the signature of a finder method, and being generated automatically - * by the Hibernate Metamodel Generator. + * the signature of a finder method, with an implementation + * generated automatically by the Hibernate Metamodel Generator. *

- * For example: + * For example, suppose the entity {@code Book} is defined as follows: + *

+ * @Entity
+ * class Book {
+ *     @Id String isbn;
+ *     String title;
+ *     ...
+ * }
+ * 
+ *

+ * Then we might define: *

  * @Find
  * Book getBookForIsbn(String isbn);
@@ -28,6 +38,55 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
  * List<Book> getBooksWithTitle(String title);
  * 
*

+ * Notice that: + *

+ *

+ * The Metamodel Generator automatically creates an "implementation" + * of every finder method in the static metamodel class {@code Books_}. + * The generated method may be called according to the following + * protocol: + *

+ * Book book = Books_.findBookByIsbn(session, isbn);
+ * List<Book> books = Books_.getBooksWithTitle(session, String title);
+ * 
+ *

+ * Notice the extra parameter of type {@code EntityManager} at the + * start of the parameter list. + *

+ * Alternatively, the type to which the annotated method belongs may + * also declare an abstract method with no parameters which returns + * one of the types {@link jakarta.persistence.EntityManager}, + * {@link org.hibernate.StatelessSession}, + * or {@link org.hibernate.Session}, for example: + *

+ * EntityManager entityManager();
+ * 
+ * In this case: + * + *

+ * Thus, the generated method may be called according to the following + * protocol: + *

+ * Books books = new Books_(session);
+ * Book book = books.getBookForIsbn(isbn);
+ * List<Book> books = books.getBooksWithTitle(String title);
+ * 
+ *

+ * This is reminiscent of traditional DAO-style repositories. + *

* The return type of an annotated method must be an entity type {@code E}, * or one of the following types: *

* + * @see HQL + * @see SQL + * * @author Gavin King * @since 6.3 */ diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/processing/HQL.java b/hibernate-core/src/main/java/org/hibernate/annotations/processing/HQL.java index 030fc8e521..1651cbe616 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/processing/HQL.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/processing/HQL.java @@ -17,8 +17,8 @@ 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. + * {@linkplain #value HQL query}, with an implementation generated + * automatically by the Hibernate Metamodel Generator. *

* For example: *

@@ -36,11 +36,44 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
  * 

* The Metamodel Generator automatically creates an "implementation" * of these methods in the static metamodel class {@code Books_}. + * The generated methods may be called according to the following + * protocol: *

  * Book book = Books_.findBookByIsbn(session, isbn);
  * List<Book> books = Books_.findBooksByTitleWithPagination(session, pattern, 10, 0);
  * 
*

+ * Notice the extra parameter of type {@code EntityManager} at the + * start of the parameter list. + *

+ * Alternatively, the type to which the annotated method belongs may + * also declare an abstract method with no parameters which returns + * one of the types {@link jakarta.persistence.EntityManager}, + * {@link org.hibernate.StatelessSession}, + * or {@link org.hibernate.Session}, for example: + *

+ * EntityManager entityManager();
+ * 
+ * In this case: + * + *

+ * Thus, the generated methods may be called according to the following + * protocol: + *

+ * Books books = new Books_(session);
+ * Book book = books.findBookByIsbn(isbn);
+ * List<Book> books = books.findBooksByTitleWithPagination(pattern, 10, 0);
+ * 
+ *

+ * This is reminiscent of traditional DAO-style repositories. + *

* The return type of an annotated method must be: *