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!
Related
I have two databases with only two deficiencies: URL and data, the tables are the same, even some tables's contents are the same.
I have managed two have each one as a separate datasource following this tutorial : https://www.baeldung.com/spring-data-jpa-multiple-databases .
However, code maintainability is hard, all made modifications on an entity, repository or even entity id class in one datasource have to be duplicated to the other one each time.
I am looking for configurations or practices or even ideas to make the code maintainability easier.
using spring 2.7.4
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.
I'm studying Spring boot, and i have create several entity, my problem now is to retrieve the data from controller to save it on db.
Surfing on the web I have learned that i have to use JPARepositery or CrudRepositery in this way:
An example with User entity
public interface UserRepository extends CrudRepository<User, Integer> {
}
and to save
User user = new User();
userRepository.save(user);
But if I have many entities, Do I need to create a repository for each entity?
I have read about Session, FactorySession and Transaction they are compatible with Spring boot? How it works? and #Transactional tag how it works?
Thanks in advance
Yes, usually you need to create one Repository per Entity. This is also a good practice because you are placing operations and queries related to the same Entity in the same Repository.
Yes, you can obtain a Session and a FactorySession object (Hibernate), but I would advice you against using Hibernate directy. Instead, it is better to use Spring Data or JPA mechanisms to access your database (just as you do using a Repository). The reason is because Hibernate is an implementation of the JPA standard and today we use JPA to access databases (because it masks the exact implementation of the ORM). This way you can later (potentially) replace Hibernate with another JPA implementation (such as EclipseLink) without the need to change your code (in theory). In most projects you will find Hibernate being used, however.
Yes, Transaction is a Spring annotation and an important database transaction mechanism in Spring Boot, too.
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.
We are currently using Spring 3.2.3 + JPA (Hibernate). We use aspects for transaction support as opposed to annotations. We write out own entity services (read: repositories) to abstract the persistence away from our application.
I've read a lot about Spring Data and feel it would make our code considerably cleaner and more robust. I wonder though, are there any gotchas that I should consider before transitioning?
Thanks
If you're already on JPA the transition should be as easy as it can be: activate the repositories, point the infrastructure to your EntityManagerFactoryBean and off you go.
Transactions should just work fine as well. The annotation based usage within Spring Data is selectively activated for the repository beans only. They are configured to take part in existing transactions by default, so any custom larger scoped transaction setting should be in effect already.