Skip to content

Basic Queries

TorpedoQuery provides a fluent API for building JPA queries. Let's explore the fundamental query operations.

Creating a Query Root

Every query starts with a call to the from method to specify the entity you're querying:

Entity entity = from(Entity.class);

This creates a proxy object that captures the methods you call on it to build the query.

SELECT Queries

Selecting the Entire Entity

To select all fields from an entity:

Entity entity = from(Entity.class);
Query<Entity> query = select(entity);

Generated HQL: SELECT entity_0 FROM Entity entity_0

Selecting Specific Fields

To select specific fields:

Entity entity = from(Entity.class);
Query<String> query = select(entity.getCode());

Generated HQL: SELECT entity_0.code FROM Entity entity_0

Selecting Multiple Fields

To select multiple fields (returns an array of Objects):

Entity entity = from(Entity.class);
Query<Object[]> query = select(entity.getCode(), entity.getName());

Generated HQL: SELECT entity_0.code, entity_0.name FROM Entity entity_0

Selecting from Chained Properties

You can select properties from nested objects:

Entity entity = from(Entity.class);
Query<String> query = select(entity.getSubEntity().getCode());

Generated HQL: SELECT entity_0.subEntity.code FROM Entity entity_0

Executing Queries

Getting a Single Result

Entity entity = from(Entity.class);
where(entity.getId()).eq("123");
Query<Entity> query = select(entity);
Entity result = query.get(entityManager);

Getting Multiple Results

Entity entity = from(Entity.class);
Query<Entity> query = select(entity);
List<Entity> results = query.list(entityManager);

Parameters Handling

TorpedoQuery automatically handles parameters in your queries. Values are automatically parameterized to prevent SQL injection:

Entity entity = from(Entity.class);
where(entity.getName()).eq("test");
Query<Entity> query = select(entity);

// Get the query string and parameters
String hql = query.getQuery();
Map<String, Object> parameters = query.getParameters();

// Will contain: {"name_1": "test"}

Entity Name Resolution

TorpedoQuery intelligently resolves entity names based on JPA annotations:

// If your entity class has @Entity(name = "myEntity")
@Entity(name = "myEntity")
public class EntityWithAnnotationName {
    // ...
}

// Your query will use the defined name
EntityWithAnnotationName entity = from(EntityWithAnnotationName.class);
Query<EntityWithAnnotationName> query = select(entity);
// Generates: SELECT myEntity_0 FROM myEntity myEntity_0

Query Reuse

Once you've defined a query, it's immutable - which means you can safely reuse it:

Entity entity = from(Entity.class);
Query<Entity> select = select(entity);
// Use select query for one purpose

Query<String> select2 = select(entity.getName());
// Use select2 for another purpose

The original select query remains unchanged.

Handling Primitive Types

TorpedoQuery properly handles primitive types in your entities:

Entity entity = from(Entity.class);
where(entity.getPrimitiveInt()).eq(10);
Query<Entity> query = select(entity);

Generated HQL: SELECT entity_0 FROM Entity entity_0 WHERE entity_0.primitiveInt = :primitiveInt_1

Date and Time Fields

Working with date fields:

Entity entity = from(Entity.class);
where(entity.getDateField()).gt(new Date());
Query<Entity> query = select(entity);

Generated HQL: SELECT entity_0 FROM Entity entity_0 WHERE entity_0.dateField > :dateField_1

Character Fields

Entity entity = from(Entity.class);
where(entity.getSmallChar()).eq('c');
Query<Entity> query = select(entity);

Generated HQL: SELECT entity_0 FROM Entity entity_0 WHERE entity_0.smallChar = :smallChar_1

Polymorphic Queries

Working with inheritance hierarchies:

Entity entity = from(Entity.class);
where(entity).eq(ExtendEntity.class);
Query<Entity> query = select(entity);

Generated HQL: SELECT entity_0 FROM Entity entity_0 WHERE entity_0.class = ExtendEntity

Dynamic Object Creation

TorpedoQuery supports creating objects directly from query results:

Entity entity = from(Entity.class);
Query<ProjectionEntity> query = select(dyn(new ProjectionEntity(
    param(entity.getCode()), param(entity.getIntegerField()))));

Generated HQL: SELECT new org.torpedoquery.jpa.test.bo.ProjectionEntity(entity_0.code, entity_0.integerField) FROM Entity entity_0

This technique is useful for projections and DTOs.