Search code examples
javaspringspring-dataone-to-onespring-data-jdbc

Spring Data JDBC fetch one to one


I have this domain model:

final class Project {

    private final @Id
    @With
    long projectId;

    private final String projectType;

    @With
    private final ProjectRecipient projectRecipient;

    @With
    private final Set<PreCalculationCosts> preCalculationCosts;

    @With
    private final Set<PostCalculationCosts> postCalculationCosts;
}

The problem:

When i call the findById method from the CrudRepository the property projectRecipient gets materialized.
I even see all the issued sql statements being necessary for that in the logs.

When i use my own Query only the One to Many properties are getting materialized (there is no select statement issued for the one to one related projectrecipient):

select p.* from project p 
inner join projectrecipient pr on pr.project = p.projectid
where p.projectid = :projectId

EDIT
When i debug the findById method and use this generated SQL as Query value, it gets materialized the right way. Problem with that is, that my Project table has tons of columns, so the Query value string is kind of 5 lines in my IDE(A) ...

On the other hand, i cant use the findById method because i need some postgres specific similar to clause ...


Solution

  • Currently there is no alternative to spelling out the full SQL statement including the columns for the referenced entity prefixed with the relationship name and an _. If you don't include these columns the referenced entity will be considered to be null

    The Spring Data team is thinking about enabling a way to provide everything but the select clause of a query, but it will take quite some time until these thoughts turn into code since the need some other substantial other changes.

    Note that you can extract the query or parts thereof into static final values, which might make it easier to digest.

    Also note that you can combine * notation with explicit columns (at least in the databases I worked with, so something like this would be fine:

    select p.*, pr.id as recipient_id
    

    Of course, the question if this is a good idea might cause some debate.