Query interceptor for spring-data-mongodb for soft deletions - spring

I want to add where condition to all repository fetching methods for not viewing deleted items. In Spring JPA it's possible to add #Where annotation to Entity. But for Spring Data MongoDB AFAIK it's not possible. Tried Mongodb lifecycle events but not succeeded. Is there a way of modifying repository queries before execution.

Can you explain what do you mean with "viewing deleted items"? If you want, you can use MongoTemplate and write your own repository and so can add desired where condition to every method

Related

Filter data before onSaveAll execution

I have a spring-mongo application with javers integrated which provides #JaversSpringDataAuditable annotation. Now the problem is for some of my repositories i do not want to save all data for audit which means i want to filter the data before JaversSpringDataAuditableRepositoryAspect.onSaveAllExecuted() is called.
Since, this is an advice , i cannot write another advice on top of it.
Is there any way to achieve this?
I found a nice way to do it. With Javers 5.9.4 and above , you can now write custom aspects to filter data before javers audits it. Read it here : https://medium.com/#ketannabera/auditing-in-java-application-using-spring-boot-mongodb-part-3-9729eb5ba62b

JPA Repository, specify the fetch mode for specific methods

I'm using JPA and Hibernate for my Spring Project.
I created my db/entities and for some specific API I would like to improve my queries.
I think that for these, only for these specific scenarios, I need to use some joins. So, in practically, I need to have a different fetch mode (from LAZY to EAGER).
Is there a way to specify the fetch mode into my JPA repository for a specific method? Or have I to write the JPQL queries (or Criteria queries)?
You can use Named entity graphs to control fetch mode in any level of the object graph.

Can a commit be reverted in Javers?

I have a scenario where in case a subsequent operation fails, a commit or a shallow delete might need to be reverted. This would be particularly useful in scenarios involving Mongo where there is no atomicity available across collections. Is this possible with Javers?
There is no 'rollback' option for now. It can be implemented in the future but there could be some limitations.
You could annotate your method with #Transactional annotation and if an exception occurs the database updates that occurred within that method would rollback which should include the Javers tables.
https://www.logicbig.com/tutorials/spring-framework/spring-data-access-with-jdbc/transactional-roll-back.html
Alternatively, you could use Spring AOP to perform a custom rollback and then delete the committed records manually.
How to call a custom rollback method in Spring Transaction Management?
Hope one of these options helps you.
If you need to travel back in time, instead of using Javers, you should redesign your database using functional programming idea called "persistent data structures". At the core of it is that you should never modify any existing data, you should always create new versions of existing entities.
You can read about persistent data structures for example here:
https://medium.com/#arpitbhayani/copy-on-write-semantics-9538bbeb9f86
https://medium.com/#mmdGhanbari/persisting-a-persistent-data-structure-3f4cfd46036

Spring Transaction propagation: can't get the #OneToMany related entities when using the same transaction for creation and consultation operation

I have the following problem: I am working on a spring-boot application which offers REST services and use a relational (SQL) database using spring-data-jpa.
I have two REST services:
- a entity-creation service, which create the child-entity, the parent-entity and associate them in a same transaction. When this service ends, the data are committed into the database.
- an entity consultation service, which get back the parent-entity with its children
These two services are annotated with the #Transactional annotation. It production case, it works well: I can create an parent-entity with its children in one transaction (which is commited/ended), and get it in another transaction latter.
The problem is when I want to create integration-tests. My idea was to annotate each test with the #Transactional annotation, and do a rollback after each test. This way I keep my database clean between each test, and I don't have a generate the schema again or clean all the records in the database.
The integration test consists in creating a parent and its children and then reading it, everything in one transaction (as the test is annotated with #Transaction). When reading the entity previously created in the same transaction, I can get the parent entity, but the children are not fetched (null value). I am not sure to understand very well the transaction mechanism: I was thinking that using the #Transactional on the test method, the services (annotated with "#Transactional") invoked by this test should detect and use the same transaction opened by the test method (the propagation is configured to "REQUIRED"). Hence as the transaction uses the same EntityManager, this one should be able to return the relation between the parent entity and its children created previously in the same transaction, even if the data has not been committed to the database. The strange thing is that it retrieve the parent entity (which has not been yet committed into the database), but not its children. Is my understanding of the transaction concept correct? If not, could someone explains me what am I missing?
Also, if someone did something similar, could he explain me how he did it please?
My code is quite complex. I first want to know if I understand well how are transaction managed and if someone already did something similar. If really it is required, I can send more information about my implementation (how the transaction-manager and the entity-manager are initialized, the JPA entities, the services etc...)
Binding the Entity-manager in my test and calling its flush method from my test,between the creation and the reading, the reading operation works well: I get the parent entity with its children. But the data are written into the database during the creation to read it latter during the read operation. And I don't want the transaction to be committed as I need my test to work on an empty database. My misunderstanding is not so much about the Transaction mechanism, but more about the entity-manager: it does not keep as a cache the entities created and theirs relations...
This post help me.
Issue with #Transactional annotations in Spring JPA
As a final word, I am thinking about calling an SQL script before each test to empty my database.

Spring callback when Entity exits #Transactional context?

Does Spring have any hooks to call a method on an entity or an entity listener for each entity at the exit of a transactional context?
We're using Spring and Hibernate to manage a bunch of entities that we also index for searching. We currently use an entity listener with Hibernate's #PreUpdate method to perform a reindex when an entity is created or modified. Of course, this event only fires when one or more of the entity's own properties (i.e., values in its database row) is updated.
The problem occurs when an entity has a #OneToMany mapping for non-trivial child properties. When one of those child properties is updated, the PreUpdate callback is not called on the parent entity.
We already track when properties are updated, but we want to wait until all updates are
complete before triggering a reindex. What is the best place to put such a reindex call? PreUpdate works well for most cases, but this wrinkle led me to wonder if there was a hook for when an entity leaves a #Transactional scope. Alternatively, is there a Hibernate way to trigger a callback on the parent when a OneToMany child is persisted?
i think aspect is for rescue. have a look section 10.5.8 Advising transactional operations Advising transactional operations in spring documentation this will help you to write aspect around #Transactional method and then you do indexing.

Resources