Using JPA and JDBC together - jpa

In my project, we are upgrading an old J2EE application to Java EE 6.
Since the business logic is quite complex, we want to retain the EJB + DAO code as much as possible. The old code uses plain JDBC for database persistence.
But in our new/upgraded application, we plan to use JPA.
We would like to use JPA for all the read operations on database and use JDBC for the writes (inserts/updates/deletes). Is this possible in the same transaction?
For example:
obtain an Entity Manager reference and read an employee record from the database (employee entity) using entity manager find (or a named query)
convert the entity instance to a POJO
update the POJO
perform some business logic on the POJO (reuse old code as-is)
create a JDBC connection and use a prepared statement to update the employee record in database (reuse old code as-is)
Questions:
If I open 2 separate connections to the database - one from JPA and another from JDBC, will it still be in the same transaction (since app server manages the JTA transaction)?
What are the potential issues with this approach?
Since I am updating the database via JDBC, the entity in persistence context will not be in sync with the database. How to handle caching in such cases?
I looked at the following related threads, but I would like to know more in detail.
Combining JPA and JDBC actions in one transaction
Hibernate and JDBC in one transaction

Related

Is there a way for implementing database migrations on Spring JPA without the use of frameworks (e.g.: flyway, liquidbase, etc)?

I'm migrating a system that used to be written in Jdbc Templates to Spring Data JPA. Before, we used to write the SQL queries ourselves, but now that we're modernizing our system, we're going to use Spring Data JPA for this. Due to restrictive factors, i can't implement a database migration framework, such as flyway and liquidbase. Is there any way i can implement those using what i have on Spring JPA?

Spring batch with MongoDB and transactions

I have a Spring Batch application with two databases: one SQL DB for the Spring Batch meta data, and another which is a MongoDB where all the business data is stored. The relation DB still uses DataSourceTransactionManager.
However I dont think the Mongo writes are done within an active transaction with rollbacks. Here is the excerpt from the official Spring Batch documentation on MongoItemWriter:
A ItemWriter implementation that writes to a MongoDB store using an implementation of Spring Data's MongoOperations. Since MongoDB is not a transactional store, a best effort is made to persist written data at the last moment, yet still honor job status contracts. No attempt to roll back is made if an error occurs during writing.
However this is not the case any more; MongoDB introduced ACID transactions in version 4.
How do I go about adding transactions to my writes? I could use #Transactional on my service methods when I use ItemWriterAdapter. But still dont know what to do with MongoItemWriter... What is the right configuration here? Thank you.
I have a Spring Batch application with two databases: one SQL DB for the Spring Batch meta data, and another which is a MongoDB where all the business data is stored.
I invite you to take a look at the following posts to understand the implications of this design choice:
How to java-configure separate datasources for spring batch data and business data? Should I even do it?
How does Spring Batch transaction management work?
In your case, you have a distributed transaction across two data sources:
SQL datasource for the job repository, which is managed by a DataSourceTransactionManager
MongoDB for your step (using the MongoItemWriter), which is managed by a MongoTransactionManager
If you want technical meta-data and business data to be committed/rolled back in the scope of the same distributed transaction, you need to use a JtaTransactionManager that coordinates the DataSourceTransactionManager and MongoTransactionManager. You can find some resources about the matter here: https://stackoverflow.com/a/56547839/5019386.
BTW, there is a feature request to use MongoDB as a job repository in Spring Batch: https://github.com/spring-projects/spring-batch/issues/877. When this is implemented, you could store both business data and technical meta-data in the same datasource (so no need for a distributed transaction anymore) and you would be able to use the same MongoTransactionManager for both the job repository and your step.

How to create DB Context run time?

In my asp.net core application, each client has their own database schema.
Hence there are many databases. Sometimes the tables and fields will be different.
I have used Entity Framework core as ORM and we are following Generic Repository pattern.
Is there any option to generate DB Context at run time corresponding to each client?
Thanks
Krishnan

Database Crawler using JPA

We have a requirement for building a database crawler. The application parses the tnsnames, connects to each database and retrieves some information like version, accounts, etc. We are trying to use JPA across the other parts of the application and to persist this data into the application's database.
So far, I only see creating an EntityManagerFactory programmatically for every database. Is there any other options?
We are using Spring, are there any benefits that Spring brings to the table in this scenario?
Thanks
JPA is clearly not the right tool for this job. JPA allows creating functional entities mapping a well-know database schema. Your tool doesn't know anything about the schemas and tables it will find. There could be 0 tables or 5000, with completely unknow names.
You need a much lower-level API to do what you want, like JDBC.
You could use JPA to store the results of your crawlings in a single schema, though.

Managing transactions using ADO.Net Entity framework - Update multiple databases

I need to update multiple databases in one transaction using entity framework. Means if we need to insert records in two tables of two different databases and insertion succeeds for first database but fails for other database then insertion in first database should also get rolled back.
Please let me know if we can do this using entity framework.
Thanks
Sharad Rastogi
Managing Connections and Transactions (Entity Framework)
You can use a TransactionScope to accomplish what you require.
How to: Manage Transactions in the Entity Framework
TransactionScope and ADO.NET Entity Framework