0

Assume that we have a persisted Entity object which has 10 variables, if I do for example repository.read(id) or repository.findById(id) I will get back an Entity object with every variable which is set from the repository.

Is there any way using JPAQuery or EntityManager or any other possible way, that I can make the call on the repository and get back the Entity object BUT without a specific variable being fetched as well?

I have tried the following, but it doesnt seem to do anything, still brings the Set within the response:

JPAQuery<Fruit> query = new JPAQuery<>(entityManager);
QFruit fruit = QFruit.Fruit;
Set<Apple> apple = new HashSet<Apple>();
query.select(fruit).from(fruit).where(fruit.id.eq(fruitId))
.createQuery().getParameters().remove(apple);
return query.fetchOne();
Sir. Hedgehog
  • 1,260
  • 3
  • 17
  • 40
  • That depends entirely upon whether your JPA provider supports the concept of partial objects. AFAIK Hibernate can do it but it's a bit of a fiddle. – JonK Jun 12 '19 at 15:31
  • Honestly i refure to believe that with JPAQuery there is no way to say, `.exclude(variable)` or something similar to that. – Sir. Hedgehog Jun 13 '19 at 07:43
  • 1
    What is the use case? Why would you want to do that? And DTO !=Entity – Alan Hay Jun 13 '19 at 08:52
  • My bad @AlanHay , i meant to say Entity there. Its not about the use case, point made is, that the object i want to read from the repository, is already too heavy, and it also have a OneToMany relation with another object which unfortunately is tooo heavy and this has crumbled my performance. So I want now to exclude the second object from within the first object, so I can fetch the first object with much less time cost. – Sir. Hedgehog Jun 13 '19 at 10:02
  • `@OneToMany` are lazily loaded by default. For simple properties, as the Hibernate docs note, optimisations are rarely worthwhile: *Hibernate3 supports the lazy fetching of individual properties. This optimization technique is also known as fetch groups. Please note that this is mostly a marketing feature, as in practice, optimizing row reads is much more important than optimization of column reads. However, only loading some properties of a class might be useful **in extreme cases**, when legacy tables have hundreds of columns and the data model can not be improved.* – Alan Hay Jun 13 '19 at 10:06
  • did you mean something like `Typed queries`? you can do `SELECT NEW CustomEntity(e.first, e.second) FROM Entity e` – Amit Naik Jun 13 '19 at 10:19
  • https://stackoverflow.com/questions/24710626/jpa-query-selecting-only-specific-columns-without-using-criteria-query; just a SELECT field, field in JPQL will leave the other fields "nulled". – Joop Eggen Jun 13 '19 at 10:57

2 Answers2

1

You can use any custom POJO to get your results in and specify what is selected.

https://docs.oracle.com/html/E13946_05/ejb3_langref.html#ejb3_langref_constructor

public interface AppleRepository extends CrudRepository<Apple, Long> {
    @Query("SELECT new com.mypackage.Apple(a.field1, a.field2) FROM " +
           "    Apple a ")
    List<Apple> findCustomApples();
}

Other way is to make any particular column to be Lazy Loaded. You can do that with annotation.

Borislav Markov
  • 1,495
  • 11
  • 12
  • so you are referring to a custom nativeQuery if im not mistaken. – Sir. Hedgehog Jun 13 '19 at 11:05
  • Native Query can use database specifics. I am not using database specifics. It is part of JPA-QL. The other option is to go with lazy loading and make some fields lazy and don't load them, it is up to you. – Borislav Markov Jun 14 '19 at 10:20
0

Eventually I was trying to read specific data from an entry of a Table, because the specific table has so many data it was harassing the performance, thus bringing the whole entity just for 1 or 2 variables was not correct. Eventually what helped me was Tuple. Using JPAQuery you have the advantage that you can select specific variables to be brought back from the search. e.g.

    JPAQuery<MyObject > query = new JPAQuery<>(entityManager);
    MyObject myObject  = QMyObject.MyObject ;
    Tuple response = query.select(myObject.id, myObject.version)
    .where(myObject.id.eq("12345")).or(myObject.version.eq("12345")).fetchaAll();

Then you can easily retrieve the Tuple object and handle the values as an array.

Sir. Hedgehog
  • 1,260
  • 3
  • 17
  • 40