0

I have 2 entities:

@Data
@Table("main_entities")
public class MainEntity {
    
    @Id
    private Long id;
    private String anotherId;
    @MappedCollection(idColumn = "main_entity_id")
    private SecondEntity secondEntity;
}
@Data
@Table("second_entities")
public class SecondEntity {
    
    @Id
    private Long id;
    private Long mainEntityId;
}

And exists the repository:

public interface MainEntityRepository extends CrudRepository<MainEntity, Long> {
    
    @Query("SELECT * FROM main_entities WHERE another_id = :anotherId")
    Optional<MainEntity> findByAnotherId(@Param("anotherId") String anotherId);
}

When I use the MainEntityRepository#findById(Long) - the SecondEntity is available, when I use the MainEntityRepository#findByAnotherId(String) - the SecondEntity is null

Update 2021.12.15: if set the

@MappedCollection(idColumn = "main_entity_id")
private Set<SecondEntity> secondEntities;

Its allows to get the mapped collection via MainEntityRepository#findByAnotherId(String)

2 Answers2

0

Spring Data JDBC loads 1:1 relationships with a single join and expects you to do the same when you specify a custom query.

In order to avoid ambiguities you have to use column aliases which prefix the columns with the property name of the 1:1 relation ship plus an _.

So your select should look like this:

SELECT M.ID, M.ANOTHER_ID, S.ID AS SECONDENTITY_ID, S.MAIN_ENTITY_ID AS SECONDENTITY_MAIN_ENTITY_ID
FROM MAIN_ENTITIES M
JOIN SECOND_ENTITIES S
ON M.ID = S.MAIN_ENTITY_ID
WHERE ANOTHER_ID = :anotherId

I created a complete example.

Side note: I recommend not to have an id on the non-aggregate-root entities, nor to have the reference back to the aggregate root in these entities. See Spring Data JDBC - How do I make Bidirectional Relationships?

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
-1

so you want to fetch the second entity together with your main entity with your custom method?

I thinkt it has to do with the fetch type of your main entity. It is lazy by default and if you want to load both entitys you can try to set the fetch type to eager for the second entity field in your main entity. But be aware that this is not always the best option but rather a quick fix. See here for more information about fetch types. You can also try using the join fetch as described in the accepted answer here to achieve your requested behaviour. I think that this would be the best solution.

I hope I got your question right if not please try to explain with further detail.

  • It's not hibernate – Maria Malova Dec 13 '21 at 14:10
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 13 '21 at 15:32
  • It doesn't matter if it's hibernate or not. Spring Boot is using the same principles. Have you even tried the solution of my second link? – citylightssaltpierhinocerosant Dec 13 '21 at 21:39
  • 1
    @citylightssaltpierhinocerosant It does very much matter. The OP asks about Spring Data JDBC, which doesn't have the concept of lazy loading. Spring Boot has nothing to do with this. Spring Boot "only" autoconfigures stuff implemented else where. – Jens Schauder Dec 15 '21 at 06:33