How jpa achieves schema independence - java

I am a beginner to jpa and hibernate, I understood that how jpa achieves database independence and persistence provider independence.
I came across the sentence which states
jpa can achieve schema independence
how does jpa achieves this?

JPA is an API, this API is completely abstracted from your data representation and DDL. Also, it is abstracted from the API implementation (unlike going directly for Hibernate).
This means that you can:
Use differing JPA implementations such as Hibernate or Toplink
Use different DB dialects such as Oracle, T-SQL, PostgreSQL
Implement your own JPA implementation
These can be done through annotations AND/OR configuration. So in theory you can switch from Oracle to PostgreSQL without having to recompile your application.
This also means you can do other funky things like:
Use a free, Open Source DB for development, and then Oracle/SQL Server for Production
Use Hypersonic for automated tests, so everything is in memory and torn down automatically.
Use other data-sources such as XML transparently.
You get other niceties like SQL injection protection out of the box, very quick startup time (rather than having to code everything twice), automatic DDL generation when you've defined your entities etc. which get small projects started quicker than the traditional route.
IN REALITY:
Nobody chooses to go from Hibernate to Toplink
Very few people ever implement JPA for a project
Very few people rapidly switch DB backends as each Database performs very differently
Also, the differing dialects can drive out weird bugs.
The configuration aspects and the ability to use things like Hypersonic are useful though.
The other "flip side" to the lovely API abstraction is that the implementation can be too constraining, resulting in very inefficient SQL being produced. This ends up with the developer having to add in native SQL anyway.

Schema independence can be achieved in the same way as DB and provider independence - it is possible to change the schema of all tables simply in configuration. You can change default schema in an orm.xml file included in persistence.xml via persistence-unit-defaults.
You may also specify schema via #Table annotations.

Related

JPA or JDBC, how are they different?

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

Database Layer non-ORM (Java)

I want to write Java code to work with a database, no matter which database is used. My problem is that it wouldn't be Object related. There are some insertions and queries that are but most of them aren't.
Right now we are using Postgresql and pure JDBC, but we may have to make it work with Oracle.
Can Hibernate (which I've never used) solve my problem or should I go for something else ?
I have created jOOQ precisely for that. jOOQ models SQL itself as a domain-specific language in Java. It embraces using standard and vendor-specific features, such as built-in functions, window functions, stored procedures, hierarchical queries, etc. Whenever possible, a vendor-specific functionality from one database is simulated for other databases. That way, most of jOOQ-generated SQL is compatible with any of its 13 supported databases.
See also this related question here:
ORM frameworks used for insert only / query only apps
I like #unludo's JPA answer but I thought I'd add some additional details.
I would recommend changing your code to use persistance interface that you define.
public interface DataPersister {
public void saveFoo(Foo foo);
public void findFooById(int id);
...
}
Your first implementation of the interface would then be using JDBC/Postgresql. If you want to use JPA under the covers then fine. Or if you want to switch to some no-SQL database or even flat files then fine.
Once you have the separation in your own code between the usage of the data and the persistence implementation, then it is significantly easier to switch to a different persister. You can use a cheap database like H2 for testing and switch to Postgresql in production while migrating to a new database in the near future.
Hope this helps.
Problems with Hibernate is that you need to modelize your relational database like object model. Sometimes this make difficult working with existing database. So it depends your relational database.
Other framework (not JPA) is Ibatis. Try to look at this framework.
The standard for Java is JPA and it is very powerful. Hibernate is the industry standard as a JPA provider.
JPA helps you write a clean persistence layer. You may write queries which are sure not to break, because they are validated at compilation time. I like to use spring for this, it's so easy to unit test. But CDI now provides the same I believe.
It's also easy to write test classes. As a coworker once teached me, the model is the most important thing you have. You don't want it to break or you have problems.
With JPA you may also generate the schema from the entities, for any database you want to use. From experience, it's also very good.
JPA helps you put good practices at work. That's a lot of value.
Regarding #hvgotcodes answer, yes you have to be careful with the cost but you may also mix jdbc and jpa. That's what Dao's are for.
The problem with writing your own sql is you need to manually optimize it for your RDBMS. Some RDBMS support varying sql constructs.
So you need to balance that against the overhead of switching to an ORM based solution. Or, make sure you sql is 100% standard so you don't use any constructs that work in one RDBMS solution and not in another.
In your particular situation, it's probably going to be easier to just fix your sql than rework your entire persistence layer to use ORM. Sometimes the best tool is the one you know. If your current application doesn't have a concise model layer, switching to ORM is going to require a lot of work. You could of course use hibernate and just use strait sql queries, but what's the point if you are not going to model your data.
Hopefully, all your persistence concerns are in one DAO layer, with lots of integration tests, so you can quickly identify what breaks when you switch RDBMS. If you don't have integration tests that focus on persistence, then now is the time to start writing them.

JPA and compatibility with persistance providers and databases vendors

JPA promises to be vendor neutral for persistence and database. But I already know than some persistence frameworks like hibernate are not perfect (character encoding, null comparison) and you need to adapt your schema for each database. Because there is two layers (the persistence framework and database), I would imagine they're some work to use some JPA codes...
Does anyone has some experiences with multiple support and if yes, what are the tricks and recommendations to avoid such incompatibilities ?
On the JPA level, the only thing you can do is use the JPA API of the currently used persistence library (i.e. when using hibernate, don't use Hibernate.initialize()).
On the DB level, your best bet is to keep things simple as chances of differences in behaviour grow as you move away from the most frequent use cases. Specifically, this might mean not using composite primary keys, not storing binary data, not using SQL execution at all...I'm sure others will have more good examples of practices which will allow you to move from one database to another easily.
The above made it possible for me to switch one application between PostgreSQL and Oracle and another between PostgreSQL and a few "dialects" (in hibernate lingo) of MySQL.

Hibernate Vs iBATIS [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
For our new product re-engineering, we are in the process of selecting the best framework from Java. As the consideration is to go for database agnostic approach for model, we are working on options between Struts + Spring with iBATIS or Hibernate. Please advice which is best as both offer persistence.
iBATIS and Hibernate are quite different beasts.
The way I tend to look at it is this: Hibernate works better if your view is more object-centric. If however you view is more database-centric then iBATIS is a much stronger choice.
If you're in complete control of your schema and you don't have an extremely high throughput requirement then Hibernate can work quite well. The object model makes for fairly convenient code but at a huge complexity cost.
If you're dealing with a "legacy" database schema where you need to write fairly complicated SQL queries then chances are iBATIS will work better.
HQL (Hibernate Query Language) is another language you'll have to learn and even then you'll probably find cases where you still need to write SQL. What's more, chances are you will at some spend half a day figuring out the right combination of XML, properties, annotations, etc to get Hibernate to generate a performant SQL query.
There is no universal "A is better than B" answer for this question.
Consider what you're trying to achieve. Typically, the Command Query Response Segregation
model works well for complex domains.
The reason is that you're trying to do one of two things typically:
Create/Update/Delete some complex domain entities
Run analytic fetch queries (i.e. summation/aggregation queries)
Hibernate works well for case 1 allowing you to just make a POJO and persist/update it. It also does this quickly, unless your domain is quite large.
myBatis is great for fetch queries (case 2) where you just want an answer. Hibernate would attempt to load the entire object graph and you'd need to start tuning queries with LazyLoading tricks to keep it working on a large domain. Conversely if you just want some analytic POJO page, the myBatis implementation of the same query would be trivial.
Because of this, myBatis is faster than Hibernate at SELECTS.
These two cases are the difference between Commands where you want to change the domain data and Responses where you just want to fetch some data.
So, consider these two cases and what your application does. If you have a simple domain and just fetch information, use myBatis. If you have a complex domain and persist entities, use Hibernate. If you do both, consider a hybrid approach. That's what we use on our project that has thousands of entities to keep it under control. ;)
ORM vs persistence framework
Hibernate is object-relation mapping framework (ORM) which maps Java classes to database tables. MyBatis is persistence framework - not ORM. It maps SQL statements to Java methods.
Database schema
Hibernate can create or validate database schema according to your Java model while MyBatis does not have such feature. Also it is convenient for testing environment when you're using in-memory DB. Related discussions:
Can MyBatis create the database schema?
Cache
Hibernate has first level cache which is impossible to disable. It means that if you query item through ORM and then delete it directly with SQL, it stays in the cache. You can explicitly clear the cache to get the most updated results from database. Related discussions:
Do Jpa& Hibernate load data which changes asynchronously in DB?
What are First and Second Level caching in Hibernate?
Optimistic lock management
Also there are differences for optimistic lock management:
MyBatis doesn't support optimistic concurrency control natively,
unlike ORM tools like Hibernate/JPA with the #Version annotation.
Related discussions:
Optimistic concurrency control
How to prevent concurrency issue in UPDATE via iBatis
Lazy loading
Hibernate will try to load entire object graph except objects which are marked for lazy loading. myBatis will load data according a SQL query. Lazy loading may improve performance but it may cause connection leaks if it used with
<property name="hibernate.enable_lazy_load_no_trans" value="true" />
properties. Related discussions:
org.hibernate.LazyInitializationException - could not initialize proxy - no Session
Solve Hibernate Lazy-Init issue with hibernate.enable_lazy_load_no_trans
Hibernate Session management
Entities operations like saving, updating or deleting are performed via Hibernate Session. It requires good understanding how to implement proper Hibernate Session management strategy to avoid detached entity passed to persist and other phenomenons related to Hibernate.
Sometimes it may take more time trying to understand underlying Hibernate behavior than add a little bit more work and write raw SQL statements for myBatis.
Cascading
Hibernate provides cascading, orphan removal and other features for object graphs while they not present in myBatis - to implement them you'll need to write SQL queries explicitly.
Queries
In myBatis you'll write almost plain SQL queries. Hibernate has multiple options to form query: SQL, HQL, Criteria API. Sometimes it may be suitable to use Criteria API when you have many optional fields in criteria. It would provide more structured approach to form query and maybe avoid related mistakes.
Cletus did a great job at summarizing this comparison. Hibernate works well when you control the data model and is more object-centric while iBATIS works well when you need to integrate with an existing database and is more data-centric.
Also I think that Hibernate has a bit more of learning curve. With iBATIS, it's pretty easy to know what is going on while more "magic" happens with Hibernate. In other words, newbies might find iBatis easier to use and to understand.
But I'm not saying that you should prefer iBatis, iBatis and Hibernate are just different as said above.
And by the way, if you go for Hibernate, maybe consider using standardized JPA and EJB 3.0 (JSR-220) object/relational mapping annotations provided by Hibernate Annotations.
Hibernate is an ORM, meaning (at its most basic level) it maps instances of java objects to actual rows in a database table. Generally, for pojo's retrieved via Hibernate: any manipulations and modifications to these pojo's will appear in the database. Hibernate will generate and execute the relevant SQL at an appropriate time.
Mybatis (at its most basic level) is simply a tool for piecing together and executing SQL that is stored in xml files. It does not map instances of Java objects to rows in a database table, rather it maps Java methods to SQL statements, and therefore it is not an ORM. It can also return pojo's of course, but they are not tied to any kind of a persistence context.
Both tools do a lot more than described above, but one is an ORM and one is not.
The criteria to enable you to choose which one to use, I believe, depends critically on the database model you have to work with.
For example imagine a large sprawling schema, representing some insurance model. Developers are required to retrieve
data, and interact with that data in a way that meets the business at hand.
Developer's come on go, and would never be expected to have the requisite business knowledge to write all
the sql by hand (which Mybatis would require). Hibernate would suit a scenario like that.
Business analysts define the datamodel, the entities, the relationships and the interactions, as is their expertise.
Java developer's then use Hibernate to "walk the model". The business developer's can become very productive
quickly without the need to write complicated error prone sql to run on a very complicated schema.
In my expierence, both Hibernate and Mybatis are used regularly on the same project.
Where Hibernate is being used for
General C.R.U.D functionality
'Walking' the 'domain object' relational model
Session management
and where Mybatis is being used for
ad hoc queries
kick off (and interact with) stored procedures
support very specific or intricate queries
support complicated search queries, where search criteria is dynamic, and paging of results
if you're already using Spring, I would start with Spring JDBC rather than plunging right into Hibernate or iBatis. If you write your persistence tier in terms of interfaces, you should have no problem switching implementations after you've gotten Hibernate or iBatis under your belt.
There's no reason why it has to be an "all or none" decision. Use what's best for your situation.

JPA or Hibernate for Java Persistence?

I'm researching the development of Enterprise Applications in Java, .NET and Groovy. For each platform, we're going to try how hard it is to realize a simple SOAP web service. We'll use the tools and libraries that are most commonly used, to research the real world as accurately as possible.
In this regard, when using Hibernate for persistence, would it better reflect the real world to use the new JPA (Java Persistence API), or the Hibernate custom API that existed before JPA came around?
As you're probably already aware, as of 3.2 Hibernate is JPA certified. You can easily use Hibernate as your JPA provider without having to use any of Hibernate's "custom" APIs.
I'd recommend using straight JPA with Hibernate as the provider. And use annotations rather than XML (much nicer).
Then when you need a little something extra you can always get the Hibernate Session. For example I often find I need to do this in order to pass a collection to a query as a parameter (setParameterList).
It's funny how you worded your question
new JPA ... or plain old Hibernate
Sounds like one has been around forever and the other has just been released. Of course it's not true. JPA was influenced not just by Hibernate but also by TopLink and by J2EE entity beans. The first reference to JSR 220 draft is back from 2003 - how is that for new?
If you use JPA with Hibernate you still use Hibernate and is free to apply any proprietary extensions Hibernate has.
So the choice is yours: use proprietary API or use equivalent established and standard API...
You could stick with a pure JPA spec, just in case you want to swap out Hibernate, but what you'll probably find at some point is that you're never going to swap it out, and you've been missing out on all the really great Hibernate-specific features.
I'd recommend using Hibernate directly, and as Damo suggests, annotations instead of XML. Make sure you have a firm understanding of the "magic" that Hibernate brings. If you're not careful, you could really thrash the database. For example, there's an n+1 query problem depending on how you do #OneToOne joins:
Hibernate OneToOne automatic join fetching (resolving n+1 problem)
I'd also recommend to use an embedded database for unit/integration tests on your Hibernate queries, and watch the SQL that's generated to make sure it looks like something you'd write by hand.

Categories

Resources