We use Javers with Cosmosdb MongoDb API and it works nicely. The only problem we have is that cosmosdb does not support transactions on more than one collection. We have a MongoTransactionManager bean that we use for single collection transactions but Javers pick it and try to put up a transaction with jv_snapshots and the collection we are updating.
Is there a way to configure Javers to somehow ignore the MongoTransactionManager bean present in our service ?
Related
I have a microservice created with JHipster(SpringBoot+JPA) exposing a rest api.
During a save operation over an Entity I need to manage the transaction because I must execute another update over the DB (using other Entities).
How can I do this?
Using the tradictional approach (JDBC) I got the connection and create a transaction over it, make all the queries and finally close the transaction(commit/rollback).
With JPA I have an Entity, but I find no way to specify to begin/end(manage) the transaction programmatically.
You have many alternatives, here are few ones:
define a service (a class annotated with #Service) and annotate with #Transactional the public method that implements your logic
manage transaction manually through the EntityManager injected into your service class constructor
create a custom Repository
Check the Spring docs
This is more of a Spring JPA (Hibernate) related issue than AspectJ one, I believe.
Spring Boot v2.2.2.RELEASE, Spring v5.2.2.RELEASE, Hibernate v5.4.9.Final, Spring Data Repositories
I am trying to implement Multi-tenancy in my existing single tenant application.
The tenant is chosen by the users via front-end. The tenant id is
stored in HttpSession.
An advice for Rest Controller methods, reads
the tenant id and keeps it in a ThreadLocal variable.
Now I have to enable a Hibernate Filter using the tenant id. For this, an AspectJ advice for my Repository (interface extends JpaRepository) methods work, but gets executed for each repository method call from Service.
This post is about the following (identical) implementations where the advice for enabling Hibernate Filter is fired before the advice for reading the tenant id from HttpSession. How do I correct the order? The advice for reading the tenant id does not make any repository calls.
#AfterReturning(pointcut = "execution(* javax.persistence.EntityManagerFactory+.createEntityManager(..))", returning = "entityManager")
Ref: https://github.com/spring-projects/spring-framework/issues/25125 (This thread contains a non-AOP way also - post-processing transactional EntityManager instances - That gets triggered only when the Spring Boot starts)
#AfterReturning(pointcut="bean(entityManagerFactory) && execution(* createEntityManager(..))", returning="retVal")
Ref: Access to Session using Spring JPA and Hibernate in order to enable filters
I tried setting the application property spring.jpa.open-in-view=false, but that didn't help.
I was working on a Spring-data-jpa project with spring boot, I see that the creation of repository beans required a datasoure bean to be present, Why is it so?
And can a repository bean be created without datasource bean.
The purpose of a repository is to load and save data into a persistent store.
Spring Data JPA does that using JPA so it needs an EntityManager which in turn need a DataSource.
Strictly speaking the DataSource is only used once the database is actually accessed.
While you definitely nee a DataSource bean you may delay the construction of a normal DataSource by providing a wrapper which instantiates the the actual DataSource at a later point in time.
DelegatingDataSource might be of help, either as a basis class or, since you are going to change the DataSource as a template for an implementation.
See the somewhat related question https://stackoverflow.com/a/61208585/66686
An example is if my spring controller has two Autowired services, and both services have a PersistenceContext also controled by spring (and i'm doing nothing more), will both share the same context in every request by default?
No, they will use different ones. A persistence context (EntityManager) is defined to be a thread-bound concept in JPA. Thus each request will see a fresh instance of EntityManager for each new request.
For a singleton Spring component that gets an EntityManager injected, Spring will autowire you a proxy instance so that it can easily exchange the backing instance. This a core Spring container feature and doesn't need anything in Spring Data JPA (see the documentation here).
I've got a project of mine in which I would like to take advantage of Hibernate to increase the speed of development for basic operations, combined with Spring's JDBC template to be able to use my own SQL queries for some specific operations and not loose control, since there are some heavy, performance demanding operations.
Is this even possible or a good idea?
Yes, it is possible. And yes, it's a good idea.
The documentation says:
For distributed transactions across multiple Hibernate session factories, simply combine JtaTransactionManager as a transaction strategy with multiple LocalSessionFactoryBean definitions. Each DAO then gets one specific SessionFactory reference passed into its corresponding bean property. If all underlying JDBC data sources are transactional container ones, a business service can demarcate transactions across any number of DAOs and any number of session factories without special regard, as long as it is using JtaTransactionManager as the strategy.
[...]
HibernateTransactionManager can export the Hibernate JDBC Connection to plain JDBC access code, for a specific DataSource. This capability allows for high-level transaction demarcation with mixed Hibernate and JDBC data access completely without JTA, if you are accessing only one database. HibernateTransactionManager automatically exposes the Hibernate transaction as a JDBC transaction if you have set up the passed-in SessionFactory with a DataSource through the dataSource property of the LocalSessionFactoryBean class. Alternatively, you can specify explicitly the DataSource for which the transactions are supposed to be exposed through the dataSource property of the HibernateTransactionManager class.
So, if you're in a full-stack Java EE container supporting JTA transactions and DataSources, use a DataSource defined in your Java EE container and a JTATransactionManager.
If you'e in a simple web container such as Tomcat, use a Spring-provided DataSource and a HibernatTransactionManager.