-
Notifications
You must be signed in to change notification settings - Fork 10
Entities & Tuples
-
JPA has a perfect concept of entities, but they come bundled with a restriction - they must be mapped to a real database entity (Table or View). Otherwise the validator complains. For cases when the query does not return an entity (e.g. DTO projection) the JPA spec provides Tuple. But, as you can see, the usage isn't simple: returned objects are not converted to first class Java objects like in entity case, and access to the properties is either by ordinal or string alias.
-
FluentJPA solves this problem: when used with Hibernate as a JPA provider, it uses the standard JPA mapping annotation to map Java fields to SQL query results, more on that in Returning Results. (Under the hood it registers a Hibernate specific mapper that performs conversion).
-
But this means that we need to define classes with the JPA mapping annotations, but without
@Entity
annotation, because of the 1-st restriction above. -
FluentJPA introduces
@Tuple
annotation, which should be used in place of JPA@Entity
annotation in tuple (projections) cases. Other mapping annotations, like@Column
should be used as usual. For example:@Tuple @Data //Generates getters, setters, hashCode, equals and toString. (lombok) public class AverageCost { @Column(name = "avg") private int average; }
Implementation tip: when working with Sub Queries, we need a tuple per sub query. In other words many of them. In order to not pollute packages, they can be grouped inside an interface, like this:
public interface ModeComTutorialTypes { @Tuple @Data class CrunchbaseCompany { private String permalink; private String foundedAtClean; } @Tuple @Data class CrunchbaseAcquisition { private String companyPermalink; private Timestamp acquiredAtCleaned; } ... }
Then we implement this interface and enjoy simple name resolution, i.e.:
public class ModeComTutorial implements ModeComTutorialTypes { public List<CrunchbaseCompany> method() { // ^^^^^^^^^^^^^^^^^^^^^^^----- returns a List of tuples FluentQuery query = FluentJPA.SQL(() -> { CrunchbaseCompany company = subQuery(...); CrunchbaseAcquisition acquisition = subQuery(...); ... }); return query.createQuery(getEntityManager(), CrunchbaseCompany.class).getResultList(); } }
Getting Started
- Introduction
- Setup
- Data Types
- Entities & Tuples
- Sub Queries
- JPA Integration
- Java Language Support
- Directives
- Library
- Returning Results
- JPA Repositories
Examples
Basic SQL DML Statements
Advanced SQL DML Statements
- Common Table Expressions (WITH Clause)
- Window Functions (OVER Clause)
- Aggregate Expressions
- MERGE
- Temporal Tables
Advanced Topics