简体   繁体   中英

Spring JPA Interface based projection returns null on a joined entity

I'm trying to Get Book ID along with Author entity using BookAuthorView interface.

public class Book {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @OneToOne(mappedBy = "book", cascade = CascadeType.REMOVE)
  private Author author;

  ...other properties/joined entities...

  ...getters/setters...
}

public class Author {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @OneToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "bookId")
  private Book book;

  ...getters/setters...
}

Book Repository Method

BookAuthorView getById(final Long id);

 

Projected Interface

public interface BookAuthorView {
   Long getId();
   Author getAuthor();
}

However, this results in Author property null when I receive the payload in my rest endpoint. I looked at the SQL logs and it does project all the properties of Author. Unfortunately, I don't see it in the response payload. Please let me know if I need to include more details. Any response/comment is appreciated.

This is a perfect use case forBlaze-Persistence Entity Views .

Blaze-Persitence is a query builder on top of JPA which supports many of the advanced DBMS features on top of the JPA model. I created Entity Views on top of it to allow easy mapping between JPA models and custom interface defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure the way you like and map attributes(getters) via JPQL expressions to the entity model. Since the attribute name is used as default mapping, you mostly don't need explicit mappings as 80% of the use cases is to have DTOs that are a subset of the entity model.

You can imagine Blaze-Persistence Entity-Views as bein Spring Data Projections on steroids. It's way more powerful and most importantly, allows you to model your use case.

You could use the entity Author in the BookAuthorView like this

@EntityView(Book.class)
public interface BookAuthorView {
   Long getId();
   Author getAuthor();
}

But mixing entities into this always brings trouble, so I would recommend you do this instead

@EntityView(Book.class)
public interface BookAuthorView {
   Long getId();
   AuthorView getAuthor();
}
@EntityView(Author.class)
public interface AuthorView {
   Long getId();
   String getName(); // Other attributes you need
}

Querying is a matter of applying the entity view to a query, the simplest being just a query by id.

BookAuthorView dto = entityViewManager.find(entityManager, BookAuthorView.class, id);

But the Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

It will only fetch the mappings that you tell it to fetch

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM