JPQL Entity and Attribute Naming

JPQL queries use JPA entity names and Java persistent attribute names rather than the physical database table and column names. This lets the query operate on the object model while JPA handles the mapping to SQL.

In JPQL, the name after `FROM` is normally the entity name, not the database table name. By default, an entity's name is its unqualified Java class name, such as `Customer` for a class named `Customer`. You can explicitly change it with `@Entity(name = "Client")`.

JPQL attribute references follow the Java entity model. If an entity has a field or property named `emailAddress`, a condition normally uses `c.emailAddress`, even if that attribute is mapped to a database column named `email_addr` with `@Column(name = "email_addr")`.

Path expressions navigate relationships and embedded attributes. For example, `o.customer.emailAddress` means navigate from an `Order` entity to its `customer` association and then to that entity's `emailAddress` attribute. JPQL therefore describes operations over entities and their persistent state, while the provider translates those references into the appropriate SQL identifiers.

Naming mistakes commonly occur when developers copy SQL names directly into JPQL. A query such as `SELECT * FROM customer_table` is SQL, not JPQL; JPQL instead uses entity and attribute names, such as `SELECT c FROM Customer c` and `c.emailAddress`.

The same naming principle applies to Criteria API expressions because Criteria queries also operate on the JPA entity model. With the static metamodel, an attribute can be referenced through generated types such as `Customer_.emailAddress`, reducing dependence on string-based attribute names.

Key points

Interview questions

What names do you use in a JPQL query: entity names or table names?

JPQL uses JPA entity names rather than physical database table names. For example, if the entity class is `Customer`, the default JPQL entity name is `Customer`. If `@Entity(name = "Client")` is specified, JPQL uses `Client`. The JPA provider translates that entity reference into the mapped table when generating SQL.

If a field is mapped with `@Column(name = "email_addr")`, what should JPQL use?

JPQL should use the persistent Java attribute name, such as `emailAddress`. The `@Column` annotation specifies the physical database column used for persistence. Therefore, `c.emailAddress` is valid JPQL, while `c.email_addr` is not valid merely because that is the database column name.

Can you explain a JPQL path expression such as `o.customer.emailAddress`?

A path expression navigates through persistent state in the entity model. Starting with an `Order` alias `o`, `o.customer` accesses its customer association, and `.emailAddress` accesses the customer's persistent attribute. The provider translates this object-model navigation into the necessary SQL joins and column references.

What is the effect of `@Entity(name = "Client")` on JPQL?

It assigns `Client` as the entity name used by JPQL. A query can therefore use `FROM Client c` even though the Java class might still be named `Customer`. This does not by itself change the database table name; table mapping is controlled separately, such as with `@Table`.

Why can JPQL use entity and attribute names instead of database identifiers?

JPQL is defined over the JPA persistence model rather than directly over a relational schema. The persistence provider knows how entities and persistent attributes map to tables, columns, joins, and other database structures. It can therefore translate an object-oriented query into database-specific SQL. This abstraction also allows application queries to remain decoupled from many physical schema naming details.