Search code examples
javaspring-bootspring-data-jpah2

SpringBoot Searching by forigen key entites combination in H2


I am creating a backend for a Library Management System with spring boot and H2 I created books, patrons , and borrowing entities and tables

In my borrowing controller I want to be able to insert the return date by looking for the borrowing record using only book id and patron id fields. The api call would look something like this: api/borrow/{bookId}/patron/{patronId} Therefore I need to search for the borrowing record with matching book id and patron id. Any idea how I could do this in spring boot efficiently.

Patron(User) Entity

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name="patrons")
public class PatronEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    String name;

    String phonenumber;

    String address;
}

Books Entity

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name="books")
public class BookEntity { //Representation of Data in object form and is used for Hibernate

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String title;

    private String author;

    private String isbn;

    private Integer pubyear;
}

and Borrowing entity which contain the previous two as foreign keys

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name="borrowing")
public class BorrowingEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private LocalDate borrowingdate;

    private LocalDate duedate;

    private Optional<LocalDate> returndate;

    @ManyToOne
    @JoinColumn(name = "tutorial_id", nullable = false)
    private PatronEntity patron;

    @ManyToOne
    @JoinColumn(name = "book_id", nullable = false)
    private BookEntity book;
}

Solution

  • The proper way to I found to implement this came from composite keys by defining the borrowing entity like this instead:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    @Entity
    @IdClass(BorrowingId.class)
    @Table(name="borrowing")
    public class BorrowingEntity {
    
    @Id
    private Long patronId;
    
    @Id
    private Long bookId;
    
    private Date borrowingdate;
    
    private Date duedate;
    
    private Date returndate;
    
    private BorrowingId id = new BorrowingId(this.patronId,this.bookId);
    

    For composite keys u must create a key class that stores both ID's like so:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public class BorrowingId implements Serializable {
    private Long patronId;
    
    private Long bookId;
    
    
    }
    

    Then your repository will be give the id with type BorrowingID Like so:

    @Repository
    public interface BorrowingRepo extends JpaRepository<BorrowingEntity, BorrowingId> {
    
    }