51

I was reading the "Dynamic, typesafe queries in JPA 2.0" article and stumbled upon this example:

EntityManager em = ...
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Person> c = qb.createQuery(Person.class);
Root<Person> p = c.from(Person.class);
Predicate condition = qb.gt(p.get(Person_.age), 20);
//                                     ^^ --- this one
c.where(condition);
TypedQuery<Person> q = em.createQuery(c); 
List<Person> result = q.getResultList();

I was wondering, what exactly does the underscore here mean?

Since an underscore it is a valid part of a classname I don't understand why this can be used in JPA. I checked this with an existing entity in my code and of course my class couldn't be resolved as ClassName_

Sled
  • 18,541
  • 27
  • 119
  • 168
stacker
  • 68,052
  • 28
  • 140
  • 210

2 Answers2

46

That is the metamodel for the persistance. It is how you can do type safe JPA queries in Java. It allows queries to staticly check your queries because classBar_ describes your JPA Bar. In HQL, you can easily mistype a query and not know it until it is run.

So technically, the _ does not mean anything, but it is the convention used by JPA to name a metamodel class of a JPA persistent model class. Model_ is the metamodel of Model, and it provides the names of the queryable fields and their types.

Sled
  • 18,541
  • 27
  • 119
  • 168
  • Do I have to include another maven dependecy? The `Bar_`must be known by the compiler which isn't currently the case. – stacker Feb 21 '12 at 15:09
  • 1
    Well you could write the metamodel by hand, have it generated and then copy over the files by hand, or incorporate it into your Maven build. I found [this Maven plugin](http://janistoolbox.typepad.com/blog/2010/03/java-persistency-api-20-jpa-hibernate-jpa-metamodel-generator-maven-1.html) that might do the job. – Sled Feb 21 '12 at 15:12
  • @stacker did that plug-in help? If so I'll add it to the answer itself. – Sled Feb 21 '12 at 15:40
  • Thanks for your explanation, but I decided not to depend on further libraries. I will continue using native queries ;-) – stacker Feb 21 '12 at 15:45
  • 2
    Following dependency will generate **Person_** classe. It is very useful while writing predicates. ` org.hibernate hibernate-jpamodelgen ` – M Faisal Hameed Mar 19 '18 at 02:43
  • "import javax.persistence.metamodel.SingularAttribute;" from here (I think) : https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api – granadaCoder Jun 11 '20 at 13:45
3

I found this way to declare the metamodel in this article.

/**
 * A  meta model class used to create type safe queries from person
 * information.
 * @author Petri Kainulainen
 */
@StaticMetamodel(Person.class)
public class Person_ {
    public static volatile SingularAttribute<Person, String> lastName;
}
stacker
  • 68,052
  • 28
  • 140
  • 210
  • This is what I was referring to by doing it by hand. :) I'm pretty sure that as long as you have they `@StaticMetamodel` annotation you can name the actual class whatever you like. – Sled Feb 21 '12 at 17:08