do someone of you know a way to have 2 Databases running parallel?
We are using Hibernate 4 and as a main database Postgres 9.3 - this db is hosted on another machine then the application - if the database is down we still have to save some stuff.
So first intention was to write it into a csv, but I'm not a friend of writing stuff into an unordered file. So I want just to use a fallback Database (thinking of H2 Database). Does someone has experience with such a construct?
We are also using Spring 4 - I would just set up another datasource + sessionfactory + transactionmanager - and add the name at the #Transactional method to use the right manager. any other ideas?
Thank you!!
You can extend the Spring AbstractRoutingDataSource and configure two actual data sources:
a primary PostgreSQL data source
a secondary H2 data source
The application logic will see only one data source, which is the router which will decide which data source is going to switch to on demand.
When the primary data source is down you need to instruct the router to pick the fall-back H2 one.
Related
I'm using spring boot and database mongo. Our database is placed on AWS cluster. Inside data source we have couples databases(AccountsDB, SubscriptionsDB etc). I did realization, when in Spring boot I connected to 2 databases using disable autoconfiguration in application.properties file and connect to mongoDB twice: ones, to database AccountsDB(
mongodb://${MONGO_DB_USERNAME}:${MONGO_DB_PASSWORD}#${MONGODB_HOST}:${MONGODB_PORT}/{AccountsDB}?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
), and second connection to SubscriptionDB(
mongodb://${MONGO_DB_USERNAME}:${MONGO_DB_PASSWORD}#${MONGODB_HOST}:${MONGODB_PORT}/{SubscriptionDB}?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
).
But my manager unhappy with this realization... There is any way to connect to data source without clarification of data base name? I couldn't find any solution for this, if we are not clarify its not showing any data. Thank you for any replying
I tried to connect without clarification, and it doesn't display any data
mongodb://${MONGO_DB_USERNAME}:${MONGO_DB_PASSWORD}#${MONGODB_HOST}:${MONGODB_PORT}/?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
Might be any way to connect to datasource and after using SpringJPA make connection?
Specification
Each tenant has their own database which handles users in greater detail, and there needs to exist a central database which handles:
Tokens (OAuth2)
Users (limited level of detail)
Mapping users to their database
Problem
I've found solutions for multi-tenancy which allows me to determine the datasource depending on the user. However, I'm not sure how I can also link certain crud repositories to this central datasource, and others to variable datasources.
Another solution involved updating the properties file, and using a configuration server (i.e. via git) to trigger #RefreshScope annotated configs. Though I'm not sure if this can work for Datasources, or if this could cause problems later on.
Extra Context
I'm using Spring Boot and Hibernate heavily in this project.
This blog gives a very good tutorial on how to do it.
After a lot of research it looks like hibernate just isn't built for doing that, but by manually writing the schema myself I can inject that into new tenant databases using native queries.
I also had a problem with MS Server DBs, as they don't allow simply appending ;createDatabaseIfNotExist to the JDBC URL, which meant even more native queries (Moving the project over to use MySQL anyway, so this is no longer a problem.)
I'm using Spring Boot and JDBC for my database connection. I placed schema.sql at the classpath to initialize a schema and tables.
Because the schema doesn't exist yet while connecting to the datasource, I have to configure the datasource in application.properties like so:
spring.datasource.url=jdbc:mysql://localhost:3306/
schema.sql:
CREATE DATABASE IF NOT EXISTS <schema_name>
USE <schema.name>;
CREATE TABLE...
So I select the schema after creating it. This obviously doesn't persist for too long.
How do I configure this properly? Is there a way to select a default schema after the create script or maybe change the datasource url?
With JDBC you need to use Connection.setCatalog to switch between databases. You should not use USE <databasename> as the JDBC driver itself needs to be aware of which database it is operating on.
Based on your code from the schema.sql
USE <schema.name>;
This will not work for your java environment. The schema.sql will be executed and finished, which will not cater your requirement to set the default schema.
The General approach will be to use JDBC URL as;
jdbc:mysql://localhost:3306/DB_NAME
This will set the default db as DB_NAME.
Assumptions: I am assuming that you want to connect to single node DB without any loadbalancer or failover mechanism to be used. URL may change based on these features to be configured.
If you are not specifying the DB_NAME in the URL, it means their is no default schema.
You have 2 options to access the DB in that case.
1) Always use the Connection.setCatalog() method to specify the desired database in JDBC applications, rather than the USE database statement.
2) fully specify table names using the database name (that is, SELECT dbname.tablename.colname FROM dbname.tablename...) in your SQL. Opening a connection without specifying the database to use is generally only useful when building tools that work with multiple databases, such as GUI database managers.
For more details refer to the below mysql portal for reference.
https://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
as the title says, I have an application (Spring Boot) which must execute some queries on specified objects on a SQL Server database. Such database having a single catalog and multiple schemas, which must be selected based on a previous query and some command line parameters.
I cannot seem to implement a strategy which involves Hibernate multi-tenancy, as most of the tutorials and answers on this site deal with schema names coming from a web request or an external parameter, while I need a database connection before creating the main multi-tenant EntityManager. So, I switched to a custom DataSource which tries to change the connection's default schema (using ALTER USER... WITH DEFAULT_SCHEMA = ...). But this also fails because the logged-in user does not have permission to alter his own default schema.
So I'm at a loss of what to do. Any suggestions?
Just create an EntityManager(Factory) per schema and put them in a map to choose from.
If you don't know the schemas before hand you can create EntityManager(Factory)s as soon as you learn about a schema.
that you can configure an EntityManagerFactory programatically.
I have a requirement where i need to configure a Spring based application to work with two databases. We have two databases, one that we use to keep the live data and the other database is used as a datawarehouse and contains archived data (which has the exact structure as the Live db).
To keep it simple, assume that there is a request to search for a product. What the application should do is to search for the product details in the Live database and if not found it will check the archive database.
If i need to configure such a setup, do i still need to configure to datasources and would the search code have to use the first datasource to check the live database and if not found it will run another query using the archive database?
The above is probably doable but i am wondering whether there is a better way of doing this. For example, is it possible for the application to work on a single datasource even though behind the scenes it actually works with two databases?
The application is based on Spring, JPA/Hibernate, SOAP and Mysql database and Jboss 7 as the application server.
Any examples showing how this is configured using Spring and Jboss would be very useful.
Thanks
Spring has exactly what you want - the AbstractRoutingDataSource. See this blog post on how to use it. In your case, you need to switch the datasource during one request, so you'll need to have 2 transactions, switching the datasource between them by changing the datasource indicator on the ThreadLocal:
For these DAOs, demarcate the wrapping Service-layer either with distinct packages, class names, or method names
Indicate to Spring that the Service-layer method calls should run in their own transactional contexts by annotating with #Transactional(propogation=Propogation.REQUIRES_NEW)
Create an Aspect (using AspectJ annotation #Aspect) to fire around the service-layer method calls (using #Around) to set the ThreadLocal value before the method call, and to unset it afterwards
In the #Controller, simply call the Service-layer methods. The Aspect will take care of setting the values to indicate which datasource to use, and the AbstractRoutingDataSource will use that datasource in the context of each transaction.