Spring DataSourceTransactionManager makes saves to fail - spring

I am working on a Spring Boot (2.0.2.RELEASE) application. Recently I enabled transaction management and created a DataSourceTransactionManager in the app configuration. We are using Spring Data JPA with Hibernate.
I noticed some time later that many (but not all) saves were not actual happening, but all log entries state everything was fine. Only affected saves were made by a Quartz job. Some of them were successful, but most of them not. No errors in the logs.
I since removed the transaction manager and now everything works as expected.
I assume now that DataSourceTransactionManager isn't meant to be used with JPA or Hibernate. I still don't know what to use and why this error happened.
Any help is appreciated.

Related

Spring Boot - Replicating the EntityManager created by Spring-boot

I've been working on a Spring Boot project and i did all my database operations with the help of Spring Data JPA. So all i had was some entities and some repositories and all the CRUD operations worked fine.
But now, the project needed to talk to 2 databases. So what i did was i created all the new entities and repositories in a separate package. I noticed that now i need to have 2 EntityManagers, so i created 2 config files for both of the entity managers, configuring a datasource, an entityManager and a transactionManager. So now, instead of having 1 entityManager that spring boot gave me, i had 2 entityManagers that i created myself. And they worked fine, they both talked to the database they were supposed to talk to.
My problem is that i seem to have lost a lot of feature in my entityManager that spring-boot previously gave me. For example, my entity manager no longer created the schema based on its entities in my tests, which it previously did. Along with this, i am sure that i will run into other situations in which my entityManager will not be as properly configured as the one spring-boot would have given me.
So my idea was to only declare the second entity manager, and leave the config for the first one empty, however this did not work, and looking into JpaBaseConfiguration i noticed that spring will only create an entityManager if you do not already have one.
#ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class,
EntityManagerFactory.class })
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
//some code that will give you an entity manager
);
And seeing as i MUST configure a second entityManager for the second database, it looks like im forced to create the first one as well, since spring-boot will skip creating one.
Which leads me to my question:
Is there anyway that i can configure my first entity manager the same way that spring-boot would have done it for me? Or perhaps can i force spring to give me that entityManager even though i have another one declared for the second database? Is there any other way of solving my situation (i am thinking about just using a JDBCTemplate for the second database, however this is kinda of admiting defeat :'( )?
Sorry for the long question. Any answer is appreciated! Thank you!

Configuring Spring Boot to use both H2 AND Oracle at the same time

I am writing a Spring Batch job and don't care about restarts and don't want the hassle of creating, securing and managing an Oracle schema for Spring Batch database objects. H2 on the file system is more than enough for us.
The issue is that I am writing an batch job that needs to connect to an Oracle database and failing miserably just trying to get 2 data sources, transaction managers and entity managers. Right now I am trying two H2 database and haven't even tried configuring Oracle database yet.
I have used two Oracle data sources in other Spring Boot applications successfully in the past but this is my first attempt with Spring Batch that has configuration code to create the data source.
I have tried creating two DataSource, EntityManagerFactoryBean and TransactionManager with one using default spring.datasources configuration, default bean names and #Primary.
I have tried creating just a second DataSource, EntityManagerFactoryBean and TransactionManager with different bean names. This seems to have an issue that the TransactionManager orEntityManager is already assigned to the thread.
I have tried creating a dataSource for batch but run into circular bean creation errors.
I have tried creating a BatchConfigurer and that runs into circular bean creation errors.
I have tried creating a JobRepositoryFactoryBean but a default one is still created.
I have tried using a #PersistenceContext on my #Entity classes.
It shouldn't be this hard so I must be missing something. Any help would be appreciated.
Thanks, Wes.
I think I have some success. I am able to eventually run the batch job using Spring Boot 2.2.0 and Spring Batch 4.2.0 but I have to wait for a 5 minute timeout while creating the Entity Manager for H2 for the Spring Batch repository. The Oracle Entity Manager is registered really quickly and before the H2 Entity Manager despite the H2 Entity Manager being #Primary.
I have a separate configuration class for each of my two DataSources. Each one is annotated with #Configuration, #EnableTransactionManagement and #EnableJPARepository.
The one for Spring Batch is using the standard bean names, dataSource, entityManagerFactory and transactionManager. Each #Bean is annotated with #Primary.
One setting that I needed was to add a .packages("org") to the entityManagerFactory bean. This would pick up all of org.springframework including Spring Batch.
The only other real change I have made from common implementations is to set the dialect in the JPA Properties of the Entity Manager.
I needed the spring.main.allow-bean-definition-overriding: true setting.
There may be more to my solution that I should share but I have been at this for a couple of days and have gone in circles. I even remember getting what appeared as a hung process time and and killed the job thinking it was hung. I may have had some "success" early on but just was too quick to kill the execution.
I would still like to know why it is taking so long to create the H2 Entity Manager.
Thanks, Wes.

Adding #EnableBatchProcessing causes TransactionRequiredException errors

I have a Spring Boot 2 application (still in the development stage) running well with JPA, hibernate and so on. The single persistence test I've got right now goes thru fine.
However, when I add #EnableBatchProcessing to the main boot class (the one annotated with #SpringBootApplication) I get the following error during the test phase of the maven build:
javax.persistence.TransactionRequiredException: no transaction is in
progress
If I just remove this annotation the test runs successfully again.
I read somewhere that spring Batch uses a different transaction manager than that used for JPA persistence.
How can I fix this issue?
Thanks in advance.
This is very simple.#EnableBatchProcessing annotation causes Spring Batch to automatically register a transaction manager to use for its transactions, and your JpaTransactionManager never gets used.
Reason:
By default, #EnableBatchProcessing triggers the creation of a DataSourceTransactionManager. This transaction manager knows nothing about JPA/Hibernate which causes the problem you're seeing.
Solution:
Now, if you want to change the transaction manager that Spring Batch uses for transactions, you have to implement the interface BatchConfigurer. There is a link to an example where a user has done this. What he is doing is switching the transaction manager to his own transactionmanager.

Disable hibernate hbm2ddl

I have a spring boot project that uses flyway to insert the database structure and it works perfectly except when testing. When I run my tests I can see that the flyway sql files are executed so that works however for some reason hibernate drops and creates the database structure. This only happens when in testing so it seams as if Spring is telling Hibernate to drop-create the schema when testing.
How can I completly disable the hbm2dll?
I can understand that this is the default behaviour however it this the right thing to do? Spring should never assume that someone wants hbm2dll eneabled when testing, that should be indicated by the user not spring.

Spring transaction support in Netty handlers

I am using the following versions:
Spring 3.1.1.RELEASE
Netty 3.4.0.Final
Hibernate 3.5.6-Final
Now, I have a Netty server that works fairly well - the root of the server, the pipeline factories and the base "stub" of the server that owns everything are all set up with Spring. In this stub, spring #Transactional annotations work just fine.
However, in the handlers, which are stateful and created dynamically depending on what state the user is in - #Transactional doesn't work. I'm fairly sure I understand why. I even have a "solution" - but it's not very good.
After the decoders and encoders, I add an ExecutionHandler:
pipeline.addLast("execution", new ExecutionHandler(new OrderedMemoryAwareThreadPoolExecutor(16,1000000, 1000000)));
This appears to be where the Spring transaction support is breaking. Since Spring is unaware of these threads, it can't bind any transactions to them. The classes are proxied correctly, but in debug they have no associated transactions.
My solution is crappy, and it needs to be replaced by a real solution:
Session sess = SessionFactoryUtils.getSession(getSessionFactory(), true);
That's bad because it relies on me to release the session, and it may not even be transactional, I haven't checked. It sucks in a lot of ways.
Anyway - the root of the question. Given the above tech, what's my path to getting my #Transactional notations working on the Netty handlers?
Write an ExecutionHandler that's Spring aware?
NOTE: I can't upgrade to Hibernate 4, due to lack of compatibility with Spring-Flex, used in another project in the group. Probably the same story for the Spring version, can't remember.
I suggest you create these netty's handler inside spring container and inject the service or persistence layer into the handlers so you can have these layers independence from netty and of course these are old school spring beans.

Resources