Question

Is there a way to return the full details of a joined entity instead of a link? In the example below I want to also return the details of the product, if I have list of 100 purchases, it would avoid having to make 100 calls to get the product details.

The repositories for Product, User and Purchase entities are all created using spring-data-jpa

{
  "_embedded" : {
    "purchase" : [ {
      "_links" : {
        "product" : {
          "href" : "http://localhost:8080/webapp/purchase/1/product"
        },
        "user" : {
          "href" : "http://localhost:8080/webapp/purchase/1/user"
        }
      },
      "purchasedOn" : "2014-02-23",
      "amount" : 1
    } ]
  }
}

Entities and Repositories;

@Entity
public class User {

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

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, targetEntity = Purchase.class, orphanRemoval = true)
    @JoinColumn(name = "user_id", updatable = false)
    private List<Purchase> purchases = new ArrayList<>();

}

@Entity
public class Product {

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

    private String name;

}

@Entity
public class Purchase implements Serializable {

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

    @ManyToOne
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    private User user;

    @ManyToOne(fetch = FetchType.EAGER, targetEntity = Product.class)
    @JoinColumn(name = "product_id", referencedColumnName = "id")
    private Product product;

    @Column(name = "purchase_date")
    private Date purchaseDate;

    private Integer amount;

}

@Repository
public interface PurchaseRepository extends JpaRepository<Purchase, Long> {}

No correct solution

OTHER TIPS

It would seems there is already a New Feature request for this functionality;

https://jira.springsource.org/browse/DATAREST-221

https://jira.springsource.org/browse/DATAREST-243

I'll leave the question open until the feature has been implemented.

Yes.

You can use something like a TypedQuery.

So you would create a Plain Old Java Object (POJO) which holds all the columns (fields) you need. You then use a TypeQuery to get all the fields from the database and return in a custom result set (i.e. your POJO or a collection of your POJO).

Here is a an example:

TypedQuery<BookExport> q = (TypedQuery<SOME_POJO>) entityManager.createQuery(
    "select new SOME_PJOP(a.field1, a.field2, a.field2) " +
    "from SOME_ENTITY AS a",
    SOME_POJO.class);

UPDATE

It looks like you have related entities already. Assuming you are using "Eager Loading", all you need to do is perform a simple query in your repository implementation. Eager Loading means JPA will automatically select the related attributes.If you are using Jersey to serialize the result in JSON, it by default, will serialize of the fields of the result set.

Here is an example from a JPA project I recently completed. The scheme is simple. I have a "Book" entity. Each "Book" has a related "Author". Each "Author" has a first and last name. If you select a "Book" the JPA query also select the Author's first and last name. I believe that is analogous to what you are trying to accomplish:

@Override
@Transactional
public Object findOne(Serializable id) {
    Query q = entityManager.createQuery("select a from Book a where a.id = ?1");
    q.setParameter(1, id);
    return q.getSingleResult();
}

The input id is simply the Book key (a number like 105).

Hope that helps :)

You can write projecton to get the details. For example PurchaseProjection can be written as.

    @Projection(name="purchaseProduction",types={Purchase.class})
    interface PurchaseProjection{
       public User getUser();
        public Product getProduct();
        public Long getAmount();
      }

You can access the result using http://localhost:8080/webapp/purchase?projection=purchaseProduction

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top