问题描述
当前,构成我的应用程序的JPA实体有一个@NamedQueries块,其中包含许多@NamedQuery批注.这很好用,但我的某些实体具有80多个@NamedQuery批注,并且变得难以维护.现在,我需要对查询添加排序,并且不想创建其他@NamedQuery批注.
Currently, the JPA entities that comprise my application have an @NamedQueries block that contains many @NamedQuery annotations. This works well but some of my entities have over 80 @NamedQuery annotations and are getting difficult to maintain. I now need to add sorting to my queries and do not want to create additional @NamedQuery annotations.
在研究过程中,我发现了JPA 2.1 EntityManagerFactory.addNamedQuery方法.这似乎是我祈祷的答案.我可以创建一个初始化程序,该初始化程序在启动时运行,以使用建立的命名约定创建所有命名查询,并消除实体顶部的大@NamedQueries块.
During my research, I discover the JPA 2.1 EntityManagerFactory.addNamedQuery method. This seems to be the answer to my prayers. I could create an initializer that runs at startup to create all my named queries using my established naming conventions and eliminate the large @NamedQueries block at the top of my entities.
我甚至可以使用以下EclipseLink特定代码在现有NamedQuery的基础上添加新的NamedQuery.
I could even use the following EclipseLink specific code to add a new NamedQuery based on an existing NamedQuery.
TypedQuery<Portrait> tq = em.createNamedQuery("Portraits.read", Portrait.class);
String jpql = tq.unwrap(EJBQueryImpl.class).getDatabaseQuery().getJPQLString();
Query q = this.em.createQuery(jpql + " ORDER BY p.id DESC");
em.getEntityManagerFactory().addNamedQuery("Portraits.read.Id-D", q);
TypedQuery<Portrait> tq2 = em.createNamedQuery("Portraits.read.Id-D", Portrait.class);
有什么原因,我不应该使用addNamedQuery方法代替@NamedQuery注释吗?
Are there reasons, I should not use the addNamedQuery method instead of or in addition to the @NamedQuery annotation?
推荐答案
命名查询用于组织查询定义和提高应用程序性能,因为查询字符串是在批注中定义的,并且在运行时不能更改,还可以防止安全问题像sql注入一样.
Named queries are used to organizequery definition and improve application performance, because the query string is defined in an annotation and can not be changed at runtime and also prevent security issues like sql injection.
- NamedQuery的名称范围为整个持久性单元并且在该范围内必须是唯一的.所以也许最好定义正如您所说,它适用于每个班级.由于未定义,应该怎么办如果同一持久性单元中的两个查询具有相同的值,则会发生名称,但可能会部署该应用程序将失败或一个将覆盖另一个,从而导致不可预测的运行时得到结果.
-
动态命名查询(addNamedQuery)是一种混合方法,用于动态创建查询,然后将其另存为命名查询实体经理工厂.在那一点上,它变得和其他任何东西一样可能已在元数据中静态声明的命名查询.
- The name of the NamedQuery is scoped to the entire persistence unitand must be unique within that scope. So maybe is better to defineit to every class as you said. Because it is undefined what shouldhappen if two queries in the same persistence unit have the samename, but it is likely that either deployment of the applicationwill fail or one will overwrite the other, leading to unpredictableresults at runtime.
Dynamic Named Queries (addNamedQuery) is a hybrid approach todynamically create a query and then save it as a named query in theentity manager factory. At that point it becomes just like any othernamed query that may have been declared statically in metadata.
这仅在某些特定情况下有用:
This is useful in only a few specific cases:
-
它提供的主要优点是,如果存在直到运行时才知道的查询,然后又重新发出.
The main advantage it offers is if there are queries that are not known until runtime, but then reissued repeatedly.
一旦动态查询成为命名查询,它将只承担一次处理的费用.具体取决于实现方式,是在将查询注册为命名查询时支付该费用,还是将其推迟到首次执行时支付.
Once the dynamic query becomes a named query it will only bear the cost of processing once. It is implementation-specific whether that cost is paid when the query is registered as a named query, or deferred until the first time it is executed.
总而言之,最好在实体类上定义最直接与查询结果相对应的命名查询.但是动态查询在某些特定位置也有自己的位置.
To summarise it is better to define the namedqueries on the entity class that most directly corresponds to the query result. But dynamic queries also have their place at some specific points.
这篇关于我应该使用@NamedQuery批注还是addNamedQuery方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!