Write JPA entity with foreign key id, read joined entity



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!

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:

  1. 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();

}
  1. 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;

}
  1. 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.



Source: stackoverflow