I've got an Oracle database that has two schemas in it which are identical. One is essentially the "on" schema, and the other is the "off" schema. We update data in the off schema and then switch the schemas behind an alias which our production servers use. Not a great solution, but it's what I've been given to work with.
My problem is that there is a separate application that will now be streaming data to the database (also handed to me) which is currently only updating the alias, which means it is only updating the "on" schema at any given time. That means that when the schemas get switched, all the data from this separate application vanishes from production (the schema it is in is now the "off" schema).
This application is using Hibernate 3.3.2 to update the database. There's Spring 3.0.6 in the mix as well, but not for the database updates. Finally, we're running on Java 1.6.
Can anyone point me in a direction to updating both "on" and "off" schemas simultaneously that does not involve rewriting the whole DAO layer using Spring JDBC to load two separate connection pools? I have not been able to find anything about getting hibernate to do this. Thanks in advance!
You shouldn't be updating two seperate databases this way, especially from the application's point of view. All it should know/care about is whether or not the data is there, not having to mess with two separate databases.
Frankly, this sounds like you may need to purchase an ETL tool. Even if you can't get it to update the 'on' schema from the 'off' one (fast enough to be practical), you will likely be able to use it to keep the two in sync (mirror changes from 'on' to 'off').
HA-JDBC is a replicating JDBC Driver we investigated for a short while. It will automatically replicate all inserts and updates, and distribute all selects. There are other database specific master-slave solutions as well.
On the other hand, I wouldn't recommend doing this for 4-8 hour procedures. Better lock the database before, update one database, and then backup-restore a copy, and then unlock again.
Related
We have a java application which uses spring boot and hibernate.
There are many changes on entities and fields. That's why, I want to follow changes and rollback mechanism. So that, I need a version control system over database. I checked flyway and liquibase, but I think those don't solve my problem. Because my table creations and updates are handled by hibernate.
Is there any way to see which queries are executed by hibernate to change the database and which changes have occurred since the latest database change (I mean new table, column creation or refactoring)?
One way to do it (how we do it):
Use 2 databases. A reference database and a development database.
On the development database use hibernate to let it create the strucutre.
Once a development cycle is done you run liquibase diffChangelog on the reference database. It will create a changelog.xml with all changes that have been done by hibernate on the development db. Manually correct it (names, etc).
When your happy with changelog file and the development cylce is done apply the changelog onto the reference database.
Start your next development cycle and repeat.
That way you can combine the advantages of letting hibernate generate the schema and still use liquibase to have a versioned DB-Schema that is re-creatable.
Use those tools as those are dedicated for this purpose. Personally, I like Liquibase more but it's your choice.
Hibernate's schema creation mechanism should not be used in production as then your Java description of the entity would drive the creation of the tables resulting in an inefficient structure.
That feature is only there for testing purposes.
I'm investigating the possibility of using neo4j to handle some of the queries of our java web application that simply take too long to run on MSSQL as they require so many joins on large tables, even with indexes implemented.
I am however concerned about the time that it might take to complete the ETL ultimately impacting on how outdated the information may be when queries.
Can someone advise on either a production strategy or toolkit / library that can assist in reading a production sql-server database (using deltas if possible to optimise) and updating a running instance of a neo4j database? I imagine that there will have to be some kind of mapping configuration but the idea is to have this run in an automated manner, updating the neo4j database with one or more sql-server table or view contents.
The direct way to connect a MS SQL database to a Neo4j database would be using the apoc.load.jdbc procedure.
For an initial load you can use Neo4j ETL (https://neo4j.com/blog/rdbms-neo4j-etl-tool/).
There is however no way around the fact that some planning and work will be involved if you want to keep two databases in sync (and if the logic involved goes beyond a few simple queries) continiously. You might want to offload a delta every so often (monthly, daily, hourly, ...) into CSV files and load those (with CYPHER syntax determining what needs to be added, removed, changed or connected) with LOAD CSV.
Sadly enough there's no such thing as a free lunch.
Hope this helps,
Tom
I have a working code that basically copies records from one database to another one using JPA. It works fine but it takes a while, so I wonder if there's any faster way to do this.
I thought Threads, but I get into race conditions and synchronizing those pieces of the code end up being as long as the one by one process.
Any ideas?
Update
Here's the scenario:
Application (Core) has a database.
Plugins have default data (same structure as Core, but with different data)
When the plugin is enabled it checks in the Core database and if not found it copies from it's default data into the core database.
Most databases provide native tools to support this. Unless you need to write additional custom logic to transform the data in some way, I would recommend looking at the export/import tools provided by your database vendor.
I have a much used project that I am working on currently updating. There are several places where this project can be installed, and in the future it is not certain what version is used where and to what version one might be updated to in the future. Right now they are all the same, though.
My problem stems from the fact that there might be many changes to the hibernate entity classes, and it must be easy to update to a newer version without any hassle, and no loss of database content. Just replace WAR and start and it should migrate itself.
To my knowledge Hibernate does no altering of tables unless hibernate.hbm2ddl.auto=create, but which actually throws away all the data?
So right now when the Spring context has fully loaded, it executes a bean that will migrate the database to the current version by going through all the changes from versionX to versionY (what version it previously was is saved in the database), and manually alter the table.
It's not much hassle doing a few hard-coded ALTER TABLE to add some columns, but when it comes to adding complete new tables, it feels silly to have to write all that...
So my question(s) is this:
Is there any way to send an entity class and a dialect to Hibernate
code somewhere, and get back a valid SQL query for creating a table?
And even better, somehow create an SQL string for adding a column to a table, dialect-safe?
I hope this is not a silly question, and I have not missed something obvious when it comes to Hibernate...
have you tried
hibernate.hbm2ddl.auto=update
it retains all the database with the data and append only columns and tables you have changed in entity.
I don't think you'll be able to fully automate this. Hibernate has the hbm2ddl tool (available as an ant task or a maven plugin) to generate the required DDL statements from your hibernate configuration to create an empty database but I'm not aware of any tools that can do an automatic "diff" between two versions. In any case you're probably better off doing the diff carefully by hand, as only you know your object model well enough to be able to pick the right defaults for new properties of existing entities etc.
Once you have worked out your diffs you can use a tool like liquibase to manage them and handle actually applying the updates to a database at application start time.
Maybe you should try a different approach. In stead of generating an schema at runtime update, make one 'by hand' (could be based on a hibernate generated script though).
Store a version number in the database and create an update script for every next version. The only thing you have to do now is determine in which version the database currently is and sequentially run the necessary update scripts to get it to the current version.
To make it extra robust you can make a unit/integration test which runs every possible database update and checks the integrity of the resulting database.
I used this method for an application I build and it works flawlessly. An other example of an implementation of this pattern is Android. They have an upgrade method in their API
http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
Don't use Hibernate's ddl. It throws away your data if you want to migrate. I suggest you take a look at Liquibase. Liquibase is a database version control. It works using changesets. Each changeset can be created manually or you can let Liquibase read your Hibernate config and generate a changeset.
Liquibase can be started via Spring so it should fit right in with your project ;-)
Its adds new ones, but as far as I can see it does not drop the old ones ?
When I say old ones, I mean properties of entity objects that are now completely removed,where previously they were present and annotated with #column
Are my only options to drop the col manually or change the config value to create ? Neither of which are particularly charming.
Or something else ?
For what it's worth, never EVER use hbm2ddl.auto on any live/production database.
Yes, it is "working as intended" that "update" doesn't drop any columns that are not referenced (probably to allow you to use "legacy" databases that have columns that are not used by your hibernate app, but may be used by external applications). However, in certain circumstances, hibernate can drop and recreate columns if, for instance, you change the datatype in your entity. That is one of the reasons you should never use it for any production system.
Personally, I would never trust an automated "black box" framework to handle changes to the datamodel in anything but strictly local/dev environments. I have always set it up so in the local dev environments, you may do create-drop. Once it's time to start promoting your app to central test/stage and then prod, all database changes are done by DBA:s with good old fashioned DDL scripts. Data is far too valuable to risk on a potential bug or unexpected behavior in hibernate (or any other ORM/automated framework). I even make sure that the database user configured in my applications doesn't even have create/drop/alter privileges in the database, just to prevent disasters happening due to bad configuration in hibernate.
So, to answer your question - if you want hibernate to always maintain your database reflecting your entities exactly, "create-drop" is your only option. Just don't ever use it on anything but local dev databases.
I'd have a look into liquibase for keeping your database in sync with your enitities. Maybe a bit of an overkill but well worth it.