I have two entities, A
and B
that are persisted to a relational database via JPA.
public class A { @Id private String id; private String bId; } public class B { @Id private String id; private String field; }
Notice how A
does not have a B
attribute but rather just its id. In my use case at the time of persisting an A
entity the B
entity does not currently exist and is written later to the db. However, at read time I would very much like to access A
objects with their corresponding B
entity if it already exists in the database (or null otherwise) – with a single JPA query.
How could I do this?
Thanks in advance!
Advertisement
Answer
You can use a joined HQL/JPQL query along with an projection in order to achieve what you need. For example consider the following repository, entities and projection classes:
- Repository
@Repository public interface PersonRepository extends JpaRepository<Person, Long> { @Query("SELECT P.id AS id, P.detailsId AS detailsId, P.name AS name, PD as detail " + "FROM Person P " + "JOIN PersonDetails PD " + "ON P.detailsId = PD.id") List<PersonDetailProjection> findJoined(); }
- Entities
@Data @Entity(name = "Person") @Table(name = "person") public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private Long detailsId; }
And
@Data @Entity(name = "PersonDetails") @Table(name = "person_details") public class PersonDetails { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String address; }
- Projection
public interface PersonDetailProjection { Long getId(); Long getDetailsId(); String getName(); PersonDetails getDetail(); }
You can modify the query to have a WHERE
clause, but the basic gist is what you see. Note that I still fail to see why you would want to do the query like, especially considering the amount of work it takes to set it up.