Read Only Database Connection with Hibernate - java

Is it possible to use Hibernate and connect to a database with a read only connection? I will be working on a project that will require connecting to an existing database, pulling data from it, and doing some complex data manipulation in the application. Throughout all of this I can`t change anything in the database, hence the read only connection requirement.
My first thought was to pull the data from the database using Hibernate so that I can have ready made Java objects represent the data, however, I can`t seem to find any information on how to force Hibernate to use a read only database connection ... I have a feeling this might actually be impossible, but I want to find out from others before I pursue other ideas.

I don't have enough reputation to comment, apparently :(
But responding to your comment about the cases where Hibernate may still write back to the DB, you could manually detach the object from your persistence context, after which Hibernate would cease caring about the state of the object & whether its been modified.

You can use: Session.setDefaultReadOnly( true );
http://docs.jboss.org/hibernate/orm/3.5/reference/en-US/html/readonly.html#readonly-api-loaddefault

To be bullet-proof safe against anything you do in the application, you need to assign read-only permissions to the DB user that Hibernate is configured to use. This has to be done on the database side. Otherwise, if you rely only on the configuration on the application side, you can always make a mistake (forget to detach the entities, forget to set the session to read-only mode etc.).

Related

Set Hibernate Session to Read Only for Whole Application

I know you can set a session to create "read only" objects by calling setDefaultReadOnly on the session. However, I'm trying to accomplish this for the whole application so that I don't have to set the session to read only every time I interact with it.
Also just to clarify, setting the session to read only doesn't set the connection to read only, it simply disables auto commit and dirty checking for the objects created by the session. This is exactly what I'm after.
Ideally I'm trying to accomplish this in Grails, however, if anyone knows how to do this in Hibernate in general I should be able to port that over to Grails.
It's possible in grails since 2.3.0 version. See here

Initializing an HSQLDB instance and then using it in an app

I am brand new to the concept of embedded databases and have chosen HSQLDB to be the embedded DB for my Java app. I think I am fundamentally not understanding something: nowhere do I see how/where to:
Define username/password credentials that must be used for connecting to a database
Creating a new database (e..g, db_myapp)
Creating tables for that new database
With a non-embedded ("normal") DB, I would first use a DB client to connect to the database, and CREATE the db_myapp DB as well as any tables it should have. My app would then expect those tables to exist at runtime.
But with HSQLDB, I have no such DB server to connect to, so I don't see how/where I can create these databases/tables/credentials ahead of time, before my app runs.
And maybe that's exactly what an "embedded" DB does; perhaps its an entire DB embedded inside a JDBC driver? In any event, I still need a way to accomplish the 3 things listed above.
The only thing I can think of is to run some initialization code every time that my app starts up. This code would check for the existence of these constructs, and if they don't exist, then it would create them.
There are several problems here:
This approach might work with databases and tables, but not the credentials I need on the JDBC Connection itself. How/where do I create those?
I'm not even sure if this is the right/normal approach to using an embedded HSQLDB; can someone confirm I'm on track (that is, the "check-to-see-if-it-exists-and-if-not-then-create" approach)?
What happens if I accidentally execute code that tries creating a new database/table eve when it already exists? Will HSQLDB just ignore it or will it blow out my existing DB/tables?
The short answer is that you're pretty much on the right track.
Connecting to the embedded database is really no different from connecting to a normal db server, except that the connection string is a bit different. This section has information on that. The thing is that you don't really have separate 'databases' to choose from, it's just specified in the connection string. For the connection:
Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "SA", "");
This will give you a connection to an embedded database engine that persists the data in the file at /opt/db/testdb. The default username for an embedded database will always be 'SA' with no password. I honestly don't know if it'll work, but if you really need to set a different password, you can try executing ALTER USER SA SET PASSWORD <newPassword>. It'll probably work...
As far as creating tables and such, there's a couple of way of going about this, depending on whether the database will be persisted as a File or in memory. Often times, embedded dbs get used for pretty simple data, and so the tables get created by executing a statement right after initializing the connection. CREATE TABLE IF NOT EXISTS ... is the usual way of doing things. This allows you to create a table only if it doesn't already exist.
If you're working with a file-base database, then hsqldb gives you another option. Take a look at this documentation about accessing a database using their tools. This would allow you to create a file-base database ahead of time, and set things like username/password and setup all your tables. Then you can just copy over the resultant file to be used by your application. Then everything would be setup before your application connects to it.
So ultimately, you have the option to go either way. You can either have your application set everything up when the connection is initialized, or you can set it up manually ahead of time. My preference is to have the application set it up in code simply because then your table definitions are kept closer to the code that actually uses them. I haven't used an embedded database like that for really complex data, though, so I can't honestly say how well that scales.

Data in cache hot swap

I have some data selected from database and cached in memory.I use them quite frequently.But sometimes I need to update this data,and I don't want to stop the server.Is there any available solutions for this?
You could use a DB cache (Try using Ehcache, it supports JDBC caching).
Or provide some external interface that you can send a message to, to tell you app to update from the DB.

Switching between embedded Databases in Java with JPA

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.

Loading a Database Table to Memory to Use

In a search application, I need to keep track of the files and their locations. Currently am using a database table for this, but since I have to connect to the db every time I need to retrieve such data, this is obviously not efficient. Is there a method I can load the table to memory and use it? I won't need to modify it while it's in the memory.
Thank You!
If all you want to do is retrieve one table into memory you can do this with a single SELECT statement. You can build a collection like a Map from the ResultSet. After that get the information you want from the Map.
You could populate any of the several Java databases out there that have an in-memory mode, like HSQLDB, Derby, or H2. You might also look at SQLite, which isn't specifically Java but has various Java connectors as described in this Q&A here on StackOverflow.
But you don't have to connect to a DB each time you need to query it, you can use a connection pool to manage a set of connections you can reuse. Since usually the main delay is establishing a connection, this can lead to quite lot per-query overhead.
You could also use one of caching products like Ehcache, Memcache, Coherence and many others. I have some knowledge in using Ehache. Configure Hibernate to cache a particular query or entity object or a POJO. All subsequent searches with same criteria will be fetched from cache.
I believe similar features are provided by other products as well.
Your sentence "I won't need to modify it while it's in the memory." does not reflect the title of your question, where you apparently want to modify an commit back your data after using it.
If you simply want to speedup your app, why don't you store your data in some kind of variable? Depending on your development tool, it could be some kind of session variable.

Categories

Resources