How to refresh Spring JPA when data is updated from querydsl directly? - spring-boot

I'm using spring data jpa and querydsl. I don't want to update directly through JPA because I have to submit a complete entity, which introduces an unnecessary query. So, I use querydsl instead:
val qRecord = QCoupon.coupon
jpaQueryFactory.update(qRecord)
.set(qRecord.useState, Coupon.STATE_ORDERED)
.set(qRecord.useTime, useTime)
.where(qRecord.id.eq(recordId))
.execute()
But the query after that in the same transcation cannot get the latest data, I think it has something to do with the first-level cache.
Adding #Modifying doesn't work because I didn't use #Query, the first annotation will be ignored.
I know EntityManager.clear() can fix that. But it looks too heavy, I'm not sure this is a good idea.
This post explained the cause of the problem very well but not my case -- I have rejected both two answers.
#Modifying is ignored.
EntityManager.clear() looks too heavy, and find() also need an entity.

Thanks #Jan-WillemGmeligMeyling 's idea. Because he didn't reply to me, I wrote it in my answer.
Have you tried refreshing the entity?
entityManager.refresh(entityManager.find(Coupon.class, recordId))
em.find() will not look up the entire table, that's what I want.

Related

Spring data update just one entity field

i’m new to spring when i try to update just one field of an entity I noticed in logs that hibernate perform two queries, before update it does a SELECT of all fields. Is that ok? Why does Hibernate perform that SELECT? How can i update a field with just one UPDATE query? Additionally when I tried to update a single title in an entity that has another nested entity i end up with a bunch of SELECT. I think it’s not good for performance or I’m wrong?
Something s = somethingRepository.findById(id);
s.setField1(someData);
somethingRepository.save(s);
On the internet I found a solution to make custom query with #Modifying and #Query(“UPDATE …”) but in this way I need to make custom query for every single field. Is there a better solution?
As per the source code you have pasted in the question
Something s = somethingRepository.findById(id);
s.setField1(someData);
somethingRepository.save(s);
if the entity Something which you are asking does not exist in the hibernate first level cache, it will make one SELECT call.
and as you are updating field 1 value then it will make another update call.
It does not matter if you are using save or not because Hibernate dirty checks will ensure that all changes are updated.
otherwise you can use custom method with #Modifying with JPQL and named params. It is more readable than ?1,
#Modifying
#Query("UPDATE Something s SET s.field = :fieldValue WHERE s.id = :id")
void updateField(String fieldValue, UUID id);
Regarding that you are seeing multiple calls "when I tried to update a single title in an entity that has another nested entity". It depends on how you have created the relationship among entities. If you can share the entities and their relationship then only it can be answered accurately.
Because internally the repository.save() method does an upsert. If you go to the inner classes and check you will see that first, it will check whether the entity is present in the database then based on that it will perform add or update. If you don't want the SELECT query to run then you can use the native query offered by the JPA repository. You can do something like this:
#Modifying
#Transactional
#Query("UPDATE <tableName> SET <columnName> = ?1 WHERE <condition>" ,nativeQuery=true)
void updateSomething(String value);

Inject a method or a code before executing #Modifying spring jpa

I have a scenario where the data is updated through Jpa repository.save() and also using JPQL with #Modiyfying annotations if I want to update one or two fields.
I have introduced EntityListener to perform operation on #PreInsert and #PreUpdate. This works like a charm when I use save() method.
CHALLENGE
I want to execute same code which I execute on EntityListener everytime any JPQL is executed through #Modifying annotation.
In short I want to inject piece of code for #Modifying operations.
Is there any way to do it? I searched but couldn't find one.
Thanks for the time.

Spring Hibernate findAll. Select only Parent class

I am having a problem. I have a oneToMany relationship. I need to have findAll methods where :
a) i can select every parent with child
b) i can select ONLY parent.
I am a little confused with lazy loading etc. How can hibernate understand what i am asking for?
Thanks in advance.
Lazy Loading can be configurable, means you configure, whether you need it or not, in case of lazy loading your data will be picked when you request for it, all the data is not handPicked at FindAll at once.
I think this link is well explanatory

JPA save/update only if modifications

I have a problem, with the Spring JPA, I did not find anything about saving entity only if there are modification. And I am not talking about saving certain fields.
After the database data is loaded by the JPA entity manager, how can I verify, before I save the entity, if there are modification/changes to the fields. Without taking each field and verify it with:
if (field != ...)
Class i = repo.findByExternalId(externalId);
...
if (modifications)
repo.save(i);
else
//don't save
I tried with dynamic-update=true but it doesn't work.
If you have some information about what to search on the web... that would be helpful as well.
Thanks.
Just don't call save() but put everything in one transaction.
JPA will do the checking for you and save changes if necessary.

spring JPA - delete by marking the entry

I would like to know if Spring or JPA has something implemented to take care of this problem.
In Entity Framework there is something similar with this.
When I want to delete an object, I don't want to remove it from the database. Instead I want to mark it as deleted by using a datetime field.

Resources