spring-bootspring-data-jpaspring-repositories

Expose Association in Entity via Rest in Spring Boot


I'm new in Spring Boot and a would like to add an association to the HTTP-Request.
Example:

// Transaction.java
@Entity
public class Transaction extends RepresentationModel<Transaction> {

  // id;

  @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
  private List<Tag> tags;

}
 
// Tag.java
@Entity
public class Tag extends RepresentationModel<Transaction> {
  // id;
  // name..., and so on
}

Now I have two Repositories:

public interface TagRepository extends JpaRepository<Tag, Long> {

}
public interface TransactionRepository extends JpaRepository<Transaction, Long> {
}

When calling GET http://localhost:8080/transactions

I get:

{
  "_embedded": {
    "transactions": [
      {
        "date": "2021-01-01T01:01:11.000+00:00",
        "and so on": "more fields" // but no "tags": [...]
        "_links": {
          "self": {"href": "http://localhost:8080/transactions/1"},
          "tags": {"href": "http://localhost:8080/transactions/1/tags"}
        }
      }
    ]
  },
  "_links": {...},
  "page": {...}
}

Is there any way to Modify the default Spring Endpoints to return an array of tags?
I would like to bypass create a custom Controller for this, because i need some parameters and filter methods.

The reason I need this function is, that I have a page which will load about 1k transactions and I don't want do make n+1 requests on GET /transactions/n/tags

Thanks for Help.


Solution

  • You need to add the join table annotation like this:

        // Transaction.java
        @Entity
        public class Transaction extends RepresentationModel<Transaction> {
        
          // id;
        
          @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
          @JoinTable(
              name = "tag_transaction",
              joinColumns = @JoinColumn(name = "transaction_id", referencedColumnName = "id"),
              inverseJoinColumns = @JoinColumn(name = "tag_id", referencedColumnName = "id"))
          private List<Tag> tags;
        
        }
         
        // Tag.java
        @Entity
        public class Tag extends RepresentationModel<Transaction> {
          // id;
          // name..., and so on
        }