Switching between embedded Databases in Java with JPA - java

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.

Related

Connecting to Multiple "Dynamic" Databases Along With Local "Static" Database in Spring Boot

I'm building an application using Java and Spring Boot where I want to query two foreign databases (they might have different schemas and data) every time I run. Therefore I'd like to query two different databases every time. After accessing those databases, I would then like to store the result (my business logic) on a local static database.
I originally wanted to store all the database data (user, pass, url) in the application.properties, but then realized that this might not be best practice as the details for the two DBs I'm querying will be received as input from the user. Therefore, I'm not sure if it's the best idea to update and overwrite application.properties every time I receive a new request (please let me know if there's a better way to do this.
Assuming I have the DBs info in application.properties, I've followed multiple tutorials for multiple DB connections in Spring, and they all followed something along the lines of making configuration files for each DB, calling a repository/DAO file for each DB, which references a model of said DB. That seems a bit problematic for me as I don't know the schema of the databases before hand, so I can't define a model class. And even if I did, this will probably change across databases, so I'm really not sure what to do.
Is there a more flexible/versatile way to query "foreign" databases with Spring or old school Java given that I don't know what their schemas might look like?
Any help is greatly appreciated!
Multiple databases config have to be maintained in application.properties or config class as a best practice. Refer here - https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-two-datasources
You can have a POJO with DB properties which gets assigned from user provided values. Use that POJO in a DB config class to connect to different databases.
Not knowing schema is not a problem as you can handle data with java collections.

How to get rid of database dependency of an already developed application having Oracle native queries?

I have an application with a huge code base which uses an Oracle database. I want to develop an hibernate app which can interact with incoming and outgoing request from the above said application without any dependencies of database.
Like if I want to change the database to mysql or postgresql it would not have any problem. Is this practical? Can it be done? Asking for help.
As to practicality, very seldom does an app ever change databases. While the idea sounds great it isn't often done and generally the benefits you can get from using built in database features sometimes outweighs the work of keeping it database independent.
As to it being done, it certainly can between SQL databases. To go from SQL to noSQL is a bit more tricky as they are in the process of supporting them in JPA. If interested in that take a look at Hibernate OGM. If you want to truly keep it so you can easily switch databases you need to stick to the JPA standard. See this on generating JPA compliant entities from the database. So long as you use ONLY JPA you can easily switch between the databases that provide a JPA implementation. Then you just include the correct implementation set the dialect and you are switched.
If you have access to change the current application it will probably be easier to just update each of the actions that contain the hard coded queries with your JPA code. If you have unit testing that would make this process much easier as well.
If you want to write something new, but not change the front end, you would need to handle whatever actions your forms on the front end are submitting. Making sure to make them available at the same path and with the same HTTP methods (GET, POST, PUT, etc.), that take the same parameters, and returning the same structure as what your actions due today.
Both approaches would allow you to go action by action replacing them. With writing something new though, replacing them one at a time is a little more difficult if both the new app and old app aren't in the same domain OR if authentication/authorization is involved.
Good luck and best wishes!

Concurrent access to same file using JPA

I have a desktop java application that can be run by different users. It makes use of JPA to access a database that is stored as a file. For this purpose I do not want to run a separate database server.
The purpose of the database is to store actions that are done in the program, it's a simple "store record" operation. But all users must be able to read these stored records.
How can I make sure the different applications can save their actions, while not overwriting the actions of the other? So I need a way to:
Open the database (file)
Lock it
Write the added action
Close the database (file)
Is there a way in JPA to do/enforce this ? I'm now using hibernate, but that's not a strict requirement.
Please do not answer with "you can do this with technology XXX". Please note that I'm concerned with respect to the concurrency issues and how to enforce that the file is opened, and closed again. How can this be done with technology XXX ?
You can try to use SQLite database file. In this case, you can achieve concurrent access to the same file (e.g. database), and in the same time you can use SQLite JDBC driver along with your JPA provider (e.g. Hibernate).
The only disadvantage might be is that, strictly saying, it's not pure Java approach, as proposed JDBC driver has native libraries bundled there, but I wouldn't consider this as an issue.
JPA is an ORM (Object-relational Mapping) specification ; the R in ORM means the same thing than the R in RDBMS. JPA is so absolutely not suitable for flat file persistence systems

Java web application memory handling

I have a Java web application which uses Hibernate for storing data into the database and retrieving them.
The strategy I am currently using is to load everything from the database on to the application at start up, and saving/updating them to the database as the user interacts with the application.
What I have also done is to keep track of Transaction history for each user as part of the business logic. (So this transaction history is all loaded on application start up).
The problem I can see is that I shouldn't load all the transaction history for all the user, because if there are a lot of the Transaction history, and users might not necessarily need to see them, then that could be a lot of memory being used up, so it is not efficient.
I was wondering if there is something similar to what PHP script can do, which is just query the database only when user request to see the transaction history, and so it is not using the server resource. (Asides from query the database) Or what are some suggestions/comments regards to what I am facing right now.
Thank you.
Query Hibernate when you need a given piece of information and let Hibernate manage putting it back to the database. This will allow Hibernate to manage the caching.
Note, that when using Hibernate, you should let Hibernate manage the data completely. Do not add or change data yourself using raw SQL.
If you are using a modern container, you should consider migrating to JPA as it is the standard in Java EE containers, allowing you to be more flexible when you need to scale. JPA is very close to Hibernate, but is an API, not an implementation, so you have more than one to choose from.
why not query hibernate for every request come in and release after response? This is a common approach.

How can I set the schema name used by hibernate entities at query time?

Our application uses Hibernate for ORM, and stores data in several schemas, accessing them with a user whose grants are customized for the application.
The schema names are determined at runtime based on data; it's not feasible to include their names in the entity mapping documents. This means that I need a way to tell Hibernate to use a specific schema name when performing lookups. Is there a way to do this?
Here's a page that lists some ways you can manage multiple schemas in Hibernate. I'd probably go with implementing your own connection provider. You'll probably want to disable caching as well.
We ran into this problem at work. I fixed it, as Robert suggests, by creating a connection provider (ie, an implementation of DataSource), called ""OracleSchemaRemappingDataSource" and using spring to do the plumbing.
Basically, this datasource implements getConnection(). The implementation of that method works by getting a connection from some other data source by spring injection, which it assumes to be an oracle connection, and then executing
ALTER SESSION SET CURRENT_SCHEMA = 'someotherschema'
and them passing that connection back.
All of the hibernate config is careful to use names without specifying schemas for them.
Also: with this, you don't want to disable caching - allow hibernate to manage connections as normal, as we are not doing any magic within the app such as using different connections on a per-user basis.

Categories

Resources