6

Have a "full Entity" class:

@Entity(name = "vacancy_dec_to_words") public class VacancyDescriptionToWords { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @JoinColumn(name = "vacancy_description_id") @ManyToOne(cascade = CascadeType.ALL) private VacancyDescription vacancyDescription; @JoinColumn(name = "words_id") @ManyToOne private Words words; @Column(name = "qty") private int qty; @Column(name = "create_date") private Date date; //...getters and setters 

In some methods I need use only 2 column from this database: word_id and qty

I try the follow way:

Projections https://docs.spring.io/spring-data/jpa/docs/2.1.2.RELEASE/reference/html/#projections

public interface QtyWords { Long getWords(); Integer getQty(); } 

JpaReposytory:

*Query, that I use tested and it workable, I use him in JpaRepository:

@Repository public interface SmallVDTWRepository extends JpaRepository<VacancyDescriptionToWords, Long> { @Query(nativeQuery = true, value = "SELECT sum(qty), words_id FROM vacancy_desc_to_words WHERE vacancy_description_id IN (" + "SELECT id FROM vacancy_description WHERE vacancy_id IN (" + "SELECT id FROM vacancy WHERE explorer_id = :exp))" + "GROUP BY words_id") List<QtyWords> getDistinctWordsByExplorer(@Param("exp") long exp); } 

But I get some interesting result when I get list of entities:

 List<QtyWords> list = vdtwService.getByExplorerId(72); 

I am not get any exceptions, but I have the list with are unknowns objects. This objects contains my data, which I need(qty and words_id), but I cannot get them from him.

enter image description here

Can I use this method (Projection) to implement this task and, in general, how to correctly implement the 'Light Entity' in this case?

1 Answer 1

5

Spring provides two mechanisms that can be used to limit data to be fetched.

Projections

Projections can help you to reduce data, retrieved from database, by setting what exactly attributes you want to fetch.

Example:

@Entity class Person { @Id UUID id; String firstname, lastname; @OneToOne Address address; } @Entity static class Address { @Id UUID id; String zipCode, city, street; } interface NamesOnly { String getFirstname(); String getLastname(); } @Repository interface PersonRepository extends Repository<Person, UUID> { Collection<NamesOnly> findByLastname(String lastname); } 

Entity graph

Annotation EntityGraph can help you to reduce amount of queries to database, by setting what exactly related entities you need to fetch.

Example:

@Entity @NamedEntityGraph(name = "GroupInfo.detail", attributeNodes = @NamedAttributeNode("members")) public class GroupInfo { @Id UUID id; @ManyToMany //default fetch mode is lazy. List<GroupMember> members = new ArrayList<GroupMember>(); } @Repository public interface GroupRepository extends CrudRepository<GroupInfo, String> { @EntityGraph(value = "GroupInfo.detail", type = EntityGraphType.LOAD) GroupInfo getByGroupName(String name); //Despite of GroupInfo.members has FetchType = LAZY, it will be fetched because of using EntityGraph } 

There are two types of EntityGraph:

  1. EntityGraphType.LOAD - is used to specify an entity graph, attributes that are specified by attribute nodes of the entity graph are treated as FetchType.EAGER and attributes that are not specified are treated according to their specified or default FetchType.
  2. EntityGraphType.FETCH - is used to specify an entity graph, attributes that are specified by attribute nodes of the entity graph are treated as FetchType.EAGER and attributes that are not specified are treated as FetchType.LAZY.

PS: Also remember that you can set lazy fetch type: @ManyToOne(fetch = FetchType.LAZY) and JPA will not fetching child entities when parent is being fetched.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, I will accept you answer, when successfuly use you tiph
When I try use EntityGraph, I get exception No identifier specified for entity: SmallVDTW. But, when I use Projections docs.spring.io/spring-data/jpa/docs/2.1.2.RELEASE/reference/… - all right, but(!) I cannot get my data from result set. I try show that in my edited question
@ValentynHruzytskyi, oh, I see the point. EntityGraph is intended to be used with entities only, but you need projections. But I can not realize, why you are not able to get data from result of vdtwService.getByExplorerId(72)? I see that you've got a collection of proxies, but you must be able to work with that proxies as with QtyWords objects.
I am question the same: "why I are not able to get data from result of vdtwService.getByExplorerId(72)? " =).`
@ValentynHruzytskyi provide a code you use to read it, with short explanation what is wrong(e.g. why you cant do this: vdtwService.getByExplorerId(72).get(0).getQty())
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.