I am new to hibernate. Learning from internet source.
As we know, with the help to Hibernate Dialect, we can easily migrate one database to another (for ex. DB2 To MySQL) i.e. only Java part we can migrate.
But how can migrate Stored Procedure and Indexing that are database specific? And can hibernate provide such feature to migrate?
Hibernate is used to store a java class object into database and retrieve it as it is. That is a ORM framework. What hibernate can help you in your DB migration as below:
1. By changing some properties like dialect, connection url, driver class etc will allow you to store/fetch the java class objects into the new DB that you are migrating to.
2. Reverse engineering: If you already have table structures (containing all the relationships between the tables) in your old DB then using reverse engineering you can create the POJO classes for hibernate.
Netbeans has built-in support for reverse engineering.
Hibernate Tool/Plugin can be used for Eclipse IDE to achieve reverse engineering.
Now, the stored procedure, triggers etc. created in your db are not from hibernate. It means hibernate have nothing to do with it. Because, the extra things (procedure, cursor, triggers etc) that are working on your database have some special purpose than a java application to store/manipulate/fetch data.
Hence, you can migrate from old DB to a new one but you won't need hibernate to migrate those extra things. Instead you can use some techniques or procedures like this Migrating Oracle Databases to SQL Server .
This things (stored procedures, triggers migration) can be done at database level and the java application has nothing to do with it.
Related
Working on a JAX-RS application which uses Microsoft-SQL-Server as a Database.
It does not use any ORM frameworks, just plain old JDBC.
Most of the application's operations involve store and retrieve data as XML into DB tables.
I have a use case where I have to run this application offline. So there wont be any connection available to DB SQL-Server.
Whilst looking into my options thought I would embed the DB and ship with the application EAR.
Looking into options I learned that, SQL-Server-Compact does not have a proper JDBC driver.
Is there any other In-Memory DB that could serve my purpose?
I want avoid any code changes like: changing the SQL queries (written specifically for Microsoft-SQL-Server).
Is there any solution which I can use and ship my application just by changing the DataSource to embedded DB?
note: I could not find any useful post on stackoverflow for this query, If it's already been discussed. Please point me to the post and I will delete this duplicate question.
If you use DAO as an interface between the application and the database, you can change the database from RDB to Hadoop (which has totally different table schema) without making any modification to the application side. (all you need to do is to change DAO.) If you use JPA, is it also easy to change the database? Can you change the database without making any modification on the application?
If yes, could you tell me how to do it?
JPA is only for RDBMS (Relational Database Management System) so yes you change change between Oracle, MSSQL, MySQL, PostreSQL etc BUT you cannot change to a NoSQL database like Hadoop or MongoDB.
To change it you have to use the Database JDBC Driver and set the Hibernate dialect (or whatever JPA implementation you use) accordingly.
My goal is to enable schema and data migration for an existing application.
This kind of question seems to have been asked many times, however with different requirements and circumstances as mine, I think.
Since I am inexperienced in this domain, allow me to lay out the architecture of the app and my assumptions first.
Architecture
The app is a multi-user, enterprise desktop application with a backend server that can persist to any major DB (MySql, Postgresql, SQL Server, Oracle DB, etc). It is assumed the DB is on-premise and maintained by our clients.
The tech stack used is a fairly common Hibernate+Spring+RMI/JMS-Combo.
Currently, migrations are done by the server in the following way:
On server start it checks for the latest expected schema version
If larger than the current version, start migration to next version until current==latest:
Create new database
Load (whole) latest schema (SQL script with a lot of CREATE TABLE ...)
Migrate data (in Java classes using 2 JDBC-Connections to old and new schema)
Load (all) latest constraints (SQL script with a lot of ALTER TABLE ...)
This migration is slow and forward-only. But it is simple. The problem is, that until now the schema scripts and the queries in the data migrations have been using MySQL-syntax and features.
Note that by migrate data I mean: the backend server copies the data from the old schema to the new one, transforming it if necessary.
Also, the migration process starts automatically on-premise of our clients. Meaning, we only have control over the JDBC connection, but no direct access to the database nor knowledge about the specific database being used (MySQL, SQL Server,...).
The goal is to either replace or augment this migration scheme with a database independent one.
Assumptions and research
StackOverflow 1 2 3 4 5 6 7: Answers state to use Hibernate's inbuilt feature. However, the docs state that this is not production ready. Also, AFAICT, all answers are concerned with schema migration only.
Liquibase: Uses a custom DSL (in XML/JSON/YAML/etc) to allow for database independent schema migration only.
DBUnit: Uses custom XML-DSL to capture snapshots of states of databases. Can not recreate a snapshot of schema version 1 to version 2.
flyway: In principle same as Liquibase. But is not database independent because SQL-Scripts are used for migrations.
JOOQ: A database independent Query-DSL in Java on top of JDBC. Comparable to Criteria API but without the drawbacks of JPA. Should in principle allow for database independent data migration, however, does not help with schema migration.
JPA-Query languages like HQL, JPQL, Criteria API are not sufficient because
One cannot reference tables not mapped by the entity manager. E.g. join tables, metadata and audit tables.
A copy of all versions of the Entity classes needs to be kept around for the mapping.
Question
I realize, that as this question stands now, it will be dismissed as opinion-based.
However, I am not necessarily looking for specific solutions to this problem ( I doubt there exists a clear solution for such a complex problem space ) but rather to validate my assumptions.
Namely, is it true, that
Liquibase and Flyway are mainly concerned with schema migration and data migration is left as an exercise for the reader?
in order for Flyway to support multiple, different databases, one needs to duplicate the migrations scripts per database?
by and large, the problem of database independent data migration remains unresolved in enterprise Java?
Even if I was to combine Liquibase/Flyway with JOOQ, I do not see how to perform a data migration, because Liquibase/Flyway migrate databases in place. The old database gets destroyed and with it the opportunity to transform the old data to the new schema.
Thanks for your attention!
Let's break it down a little bit. You're right in that this is largely opinion based, but here's what I've noticed in my experiences.
Liquibase and Flyway are mainly concerned with schema migration and data migration is left as an exercise for the reader?
You can do data migration with liquibase and flyway. It's something I've done pretty often. Take the example where I want to split a User table into User and Address tables. I'd write a migration script, which is basically just a sql file, to create the new Address table and the copy all the relevant data into it.
in order for Flyway to support multiple, different databases, one needs to duplicate the migrations scripts per database?
Possibly, flyway and liquibase are better thought of as database versioning tools. If my app needs version 10 of the database, these tools would help me get to that point. Again, the migration scripts are just basic .sql files. If you're using some mysql specific functions then those will just go in the migration script and they wouldn't work on a sql server
by and large, the problem of database independent data migration remains unresolved in enterprise Java?
Eh, I'm not sure about this one. I agree its a problem, but in practice it's not a huge one. For the past 8+ years, I've only written ansi sql. It should be portable everywhere. So in theory, we can lift those applications on to a different database. JPA and the various implementations help with those differences. Depending on how your project was built, say an application that has all of its business logic in implementation specific sql functions, then it's going to be a headache. If you're using the database for CRUD, and I'd argue that's all you should be using it for, then it's not a huge deal.
So all that said, I think you might have the wrong idea about flyway and liquibase. Like i said earlier, they aren't really 'migration tools' so much as they are database versioning tools. With a list of specific sql migration scripts that are ordered, i can guarantee the state of my database at any version. I'm not sure these are tools that I'd use to 'migrate' a legacy SQL Server based application into a PostGres based application.
I am learning Java EE and I downloaded the eclipse with glassfish for the same. I saw some examples and also read the Oracle docs to know all about Java EE 5. Connecting to a database was very simple. I opened a dynamic web project, created a session EJB , I used EntityManager and with the get methods could access the stored data table.
For my next project I had create a simple class and then access some DB table. The very first problem I encountered was that the PersistenceUnit attribute would only be recognized by EJB,Servlet etc and not a simple java class. So then I could not use the EntityManager way(or can I?)
I was asked to go via the "JDBC" way. The very first problem I encountered was to get the connection to the DB. It seems all this must be hardcoded. I had a persistence.xml with which I could easily configure the data base connection. Even setting up a driver for the DB was easy. Also there no get/set methods in the JDBC for accessing table entities.
How do I understand JPA and persistence in relation to JDBC? What was JPA thought for? Why is there set/get methods? Can someone throw some light on the essence of these two and what are the pros/cons without "jargons"?? Please also suggest some links. A simple google search for JPA and JDBC differences led me to some sites full of "terminology" I couldn't follow :(
In layman's terms:
JDBC is a standard for Database Access
JPA is a standard for ORM
JDBC is a standard for connecting to a DB directly and running SQL against it - e.g SELECT * FROM USERS, etc. Data sets can be returned which you can handle in your app, and you can do all the usual things like INSERT, DELETE, run stored procedures, etc. It is one of the underlying technologies behind most Java database access (including JPA providers).
One of the issues with traditional JDBC apps is that you can often have some crappy code where lots of mapping between data sets and objects occur, logic is mixed in with SQL, etc.
JPA is a standard for Object Relational Mapping. This is a technology which allows you to map between objects in code and database tables. This can "hide" the SQL from the developer so that all they deal with are Java classes, and the provider allows you to save them and load them magically. Mostly, XML mapping files or annotations on getters and setters can be used to tell the JPA provider which fields on your object map to which fields in the DB. The most famous JPA provider is Hibernate, so it's a good place to start for concrete examples.
Other examples include OpenJPA, toplink, etc.
Under the hood, Hibernate and most other providers for JPA write SQL and use JDBC to read and write from and to the DB.
Main difference between JPA and JDBC is level of abstraction.
JDBC is a low level standard for interaction with databases. JPA is higher level standard for the same purpose. JPA allows you to use an object model in your application which can make your life much easier. JDBC allows you to do more things with the Database directly, but it requires more attention. Some tasks can not be solved efficiently using JPA, but may be solved more efficiently with JDBC.
JDBC is a much lower-level (and older) specification than JPA. In it's bare essentials, JDBC is an API for interacting with a database using pure SQL - sending queries and retrieving results. It has no notion of objects or hierarchies. When using JDBC, it's up to you to translate a result set (essentially a row/column matrix of values from one or more database tables, returned by your SQL query) into Java objects.
Now, to understand and use JDBC it's essential that you have some understanding and working knowledge of SQL. With that also comes a required insight into what a relational database is, how you work with it and concepts such as tables, columns, keys and relationships. Unless you have at least a basic understanding of databases, SQL and data modelling you will not be able to make much use of JDBC since it's really only a thin abstraction on top of these things.
JDBC is the predecessor of JPA.
JDBC is a bridge between the Java world and the databases world. In JDBC you need to expose all dirty details needed for CRUD operations, such as table names, column names, while in JPA (which is using JDBC underneath), you also specify those details of database metadata, but with the use of Java annotations.
So JPA creates update queries for you and manages the entities that you looked up or created/updated (it does more as well).
If you want to do JPA without a Java EE container, then Spring and its libraries may be used with the very same Java annotations.
The difference between JPA and JDBC is often the deciding factor, as the two database technologies take very different approaches to work with persistent data. JDBC, allows developers to construct database-driven Java programs utilizing object-oriented semantics
JPA is database-agnostic, meaning that the same code can be used in a variety of databases with few modifications. JPA serves as a layer of abstraction that hides the low-level JDBC calls from the developer, making database coding considerably easier
hibernate is implementation of JPA
hibernate you can see further details from here about jpa Query
JDBC is a layer of abstraction on top of vendor-specific relational DB drivers. Without JDBC you would have to deal with peculiarities of a specific DB (not much fun). JDBC, however, is too low-level and entails a lot of boilerplate code.
JPA is a specification of an ORM (just an interface). It's useless without an implementation.
ORM is a kind of framework concerned with saving and retrieving objects to/from the relational DB. There are many ORMs out there with different levels of abstraction. Some of them require manually-written SQL.
Some of ORMs implement JPA (Hibernate or EclipseLink, for example). Most of them are built on top of JDBC.
Such ORMs provide the maximum level of abstraction to the point you almost never have to write SQL queries. Some people love JPA-based ORMs (they reduce boilerplate), some hate (abstraction is leaky, specification is overly complex and there are lots of corner cases).
Java analogy:
class ORM extends JDBC implements JPA {
}
Persistence layers have protocols versions so abstractions also have versions therefore you need ranges of supported versions. It is version hell
I am currently working on swign based javaSE application utlizing an embedded JavaDB for storing the data. My data model (and DB ) is fully java based utilizing JPA entities and JavaEE Persistence mechanism. No SQL scripts are used in the creation and management of the DB as everything is done by JPA.
As this application is going to be distributed to clients and clients usually require new features my question is if there is an effective way of getting the DB data and reinserting them after the updated application (with new tables, columns) has been delivered to the client.
You could use dblook (command line tool that comes with JavaDB) for an SQL dump of your JavaDB content and structure (example here).
However, many structural db changes can be done with a non-empty database as well, e.g. adding columns or adding tables.