I am using JPA and WildFly 10.
Imagine that two different companies each have subscriptions to use my application. Ideally, I'd like to split up the data of the two companies into separate databases, or at the very least, separately prefixed tables, using JPA. If a user logs in on http://example.com/company1/, it will seem as though the application is completely separate from the application running at http://example.com/company2/, when in actuality, the "two" applications are part of one application.
Multiple users may be logged in at the same time from different companies, so the database being used should be session based.
The main reason for splitting up the data into separate tables or databases is for better organization. The reason for using one application rather than multiple is to allow for horizontal scaling.
I have seen answers which state to create multiple persistence.xml files, however my application should dynamically create and drop the databases or tables based on the current subscriptions that are active. Think of it like a web hosting company, where as soon as you pay, you can login and begin working on your website; that's the direction I am moving in. Therefore, I cannot hard-code the different companies into the program.
How can this be done with JPA? Is it even possible? Or is there a better way to accomplish what I am seeking?
You are trying to make your application multi tenant capable. One way I know is:
use a field in every database table which contains a predefined value for a tenant.
set current tenant when the request comes from this tenant
then use Hibernate filtering capability to filter tenant-specific data automatically. Once the filter is activated every query will return only data specific to the current tenant.
Note: a Hibernate filter is set on the Hibernate Session object. If you are using pure JPA, the Entity Manager interface has a method called getDelegate() which returns a Hibernate session object.
Here is a link to the information about Hibernate filters. There are also tutorials on how to use them on the Internet.
Related
So as the title suggests - I need to create an application (preferably Spring Boot), which will create schemas and tables based on user input. Basically, a rest endpoint will be offered to the clients where they would upload their data model in json format. I'll be parsing the json and constructing the db artifacts (schema and tables) in runtime. And once all the tables are created, provide a rest endpoint (with unique identifier), to the client, to perform CRUD operations on their schema.
The approach I am considering currently is -
Create a super user in db , before deploying the app which will have priviliges to create new schemas and db
Create prepared statements to invoke schema/table creation on demand. The prepared statements will have place holders to take the schema name and table definition.
After proper authentication, allow users to upload their data model definition in json.
Clean the json and invoke the schema/table creation prepared statements.
Few questions that I had in mind -
Since all these DB operations will be invoked from a single super user's account, is it safe ?
The schemas and tables will be realized using native SQL queries instead of Hibernate's ORM capabilities. Is it safe/efficient ?
For the CRUD operations, is it possible to switch the db connection from super user to the client specific schema created in the earlier steps ? Or should I continue using the same super user for the CRUD operations?
It would be nice if it is possible to switch schemas in runtime using Hibernate/Spring-Boot.
What I would like is a general approach to this problem. I do not need any code.
A typical web application already has permissions to DELETE all the data for all the users.
JPA makes your queries slower, not faster. JPA can help with caching, but it doesn’t seem you need this.
Yes, you can have multiple datasources in Spring Boot. Look at this for example: https://www.baeldung.com/spring-abstract-routing-data-source
Be aware that your database might not like having millions of tables. Query planning, maintanance jobs, backups, etc all get performance penalties. Basically, databases are not designed for your use case.
I have two data bases for one system. One is OpenLDAP and another one is MongoDB. To be specific this OpenLDAP is used by Atlassian Crowd that is used by us. I need to synchronize users in these two databases. That is,
If I create a user it will be defaultly created in the OpenLDAP and it has to be created in the MongoDB as well.
In past there were issues in handling this and there may be users who are in OpenLDAP but not in MongoDB. I need to find these users also.
If I delete or update a user from one I need the delete or operation to happen in both DBs.
I am going to have a cache copy of LDAP using Redis. What is the best way to synchronize data between these two databases to match the above expectations?
If it helps I am using Java in backend.
2 possible ways:
(Preferred) Design your code in a way you can "plug" database operators to handle the different databases, so you access them from a facade code that lets you access it without worriying the underlaying databases. , so creating an user, for example, would be something like this:
createUser() -> foreach dbhandle do dbhandle->createUser() forend
The same applies to delete or update any data. This approache should also solve the problem 2.
You can just update one database and have a script that runs in background updating the databases. This approach will let you work just with 1 database, letting the script handle the rest of the databases, but it is way more expensive and less reliable (as you might access 1 database that has not been updated from the master database yet)
I am trying to create a java web application using Spring mvc. The purpose of this application is to serve different groups of users from different business units in the enterprise. So, for instance, if you think of it as a shopping experience kind of application, where the application is functionally about
picking what you want
adding what you pick to the cart
checking out from cart
then, I need to list plumbing items for plumbing department, electrical items for electrical department and and so on.
So, I decided to have two different schemas with identical table structure. So schema 'PLUMB' will store plumbing dept users who can use the application, and items related to plumbing in USERS and ITEMS table of the PLUMB schema. Similarly, electrical department has its own schema. That's for multitenancy on database side.
For the application/deployment side, the code of the webapp remains the same except for the one property that tells that application which schema it needs to query (this would be obviously different on each instance). So, I am thinking about deploying
http://mycompany.com/plumbingapp
http://mycompany.com/electricalapp
Are there any known anti patterns to this kind of architecture? I see one down side is that I will now have multiple environments to manage - like dev.mycompany.com/plumbingapp and test.mycompany.com/plumbingapp. Other than that, I think this allows for cleaner separation than having one single app that authenticates the user and then asks him to pick from which department he wants to go to and depending on department he picks, I would populate the webpage.
Have you used this kind of structure before? Are there any known down sides to this kind of design/architecture? If I deploy multiple instances, is it a multi-tenant application anymore?
depend on user and his rights, after his login, you will create /plum or /electrical modelAndView.
In your DB you may create tables plum_table and elec_table, except for user table and user_roles.
The other way is to create virtual machines and proxy to different machine depend on /plum or /electrical
The approach listed in the question suits well for two or a few tenants. But not easy to scale.
There is no need for a separate deployment bundle. The tenant identification and separation can be at only DB schema level, roles and any business rules. And the rest of the System components can be common. There is no binding reason to create a separate app for each tenant.
These posts can help help:
Databse architecture (single db vs client specific db) for Building Enterprise Web (RIA) application on cloud
Architecture for SaaS based online portal
Im currently working my way towards JPA 2.0 and I start of liking how easy it is to maintain persistent data.
What I'm currently trying to accomplish is using JPA in a basic desktop application. The application should allow me to open embedded databases which are on my file system. I chose H2 databases for now, but I can really live switching to JavaDB or anything else.
What Im trying to accomplish is, that one can open the database file without previously define a persistence-unit in the persistence.xml file.
I can easily define a unit and persist objects, but it needs to be configured first.
I want to write some sort of database browser which allows opening without preconfiguration and recompiling.
http://www.objectdb.com/java/jpa/start/connection
I saw that ObjectDB allows access for this type of PersistenceFactory creation, but I was not able to transfer this example to other databases.
Am I totally wrong with the way I approach this probblem? Is JPA not designed with on-the-fly database access?
Thank you for your help,
Johannes
Not part of the JPA standard. Some implementations may offer their own API to do it. For example with DataNucleus if you go to this page http://www.datanucleus.org/products/accessplatform_3_0/jpa/persistence_unit.html at the end you can create dynamic persistence-units (and hence EMFs), and that implementation obviously allows persistence to the widest range of datastores you'll get anywhere
You can pass a Map of properties to createEntityManagerFactory() call that defines the database connection info, etc. The property names are the same as in the persistence.xml. I assume most JPA providers support this, EclipseLink does.
You will still need to define the set of classes for the database and map them.
If you do not have any classes either, than you could look into EclipseLink's dynamic support,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Dynamic
If you want to make a database browser accessing different databases, you can't use a PU/Entity Manager (imo).
You'll need a dialogue asking a user for the IP/Port of the database, the username/password, the database name to access, and the type of database.
Then all you need to do is create a socket, send requests over the socket, and parse the response into a view.
Since both the request and the response are database specific, the user has to select the proper database driver.
I am developing an application in Java that uses Hibernate to connect to MySQL database.
My application manages students of different batches. If a student joined in 2010 then they are in the 2010 batch, so whenever the administrators of the application create a new batch, my application has to create new tables for that batch. While the scheme is much more like the old tables that are already there in the database, the table name changes. How do I accomplish this using Hibernate?
How do I create the XML files and the classes required dynamically?
If I understood your problem right, I think you want to check Hibernate Shards. Note that this is an advanced feature, unsupported and not really tested (nor maintained). So, use it at your own risk. You may want to pay special attention to the "Shard Selection Strategy" section:
http://docs.jboss.org/hibernate/stable/shards/reference/en/html_single/#shards-strategy-shardselection
From the documentation:
We expect many applications will want to implement attribute-based sharding, so for our example application that stores weather reports let's shard reports by the continents on which the reports originate
But as the others said: think twice before splitting your data. Do it only if you expect really large volumes of data. A couple million records are not really that much.