Well, they're both basically fancy wrappers/abstractors on top of SQL. The abstraction goes on multiple levels:
- first off, direct SQL queries are (almost) completely hidden away, and a higher level (but still similar to SQL in synthax) language is exposed by both frameworks. This is mainly so that your application will be independent from the various quirks of SQL as implemented by different data base vendors. Think JQuery DOM manipulation API over standard (and browser-specific) pure-Javascript. This language abstraction is called HQL (Hibernate Query Language) in Hibernate and JPQL (Java Persistence Query Language) in JPA. They are both very similar, and in fact I think JPQL has been heavily inspired by HQL. Here's a basic example:
SQL query such as
SELECT * FROM Persons
can be expressed in JPQL as:
SELECT p FROM Person p
and in HQL:
FROM Person p
Obviously there's more to it than that, and due to the fact that the frameworks, as their global name implies, try to map relational data to objects, their high-level query languages work on objects. What's important I think, to understand from the get go before delving further in the details is the fact that whatever query code you write with either JPA or Hibernate, it will be translated to SQL specific to the current database and executed against it. And Hibernate (both it by itself and its JPA implementation) has a nice feature which can log all the generated SQL . Just add the "hibernate.show_sql" (and maybe also "hibernate.format_sql") config params to true in your Hibernate config. For example for a Hibernate-JPA project, you need to add them to your persistence unit declaration, in your persistence.xml file, something like this:
<persistence>
<persistence-unit name="some_name">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<!-...->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
Try activating this feature and play around with either JPQL or HQL and see what actually happends at the SQL level. This may give you a better idea of how the higher level APIs work.
Yep, it looks weird but it has its uses (imagine trying to dynamically create a query based on some run time arguments which may or may not be set, etc)
Again, both pure-Hibernate and Hibernate JPA have very similar implementations of this API. Ang also, the queries made this way translate down to SQL that you can log and study.
As per your question regarding JPA and Hibernate and which is which, here's the story:
First there was Hibernate. A stand alone 3rd party framework, which offered a way to map SQL data to Java classes and Objects.
Then the Java EE guys thought this is a good idea, and made their own version of this, named JPA. Since these guys adhere to the philosophy of only making specs and allowing 3rd parties to make actual implementation of those specs, JPA all by itself is just a bunch of interfaces and a long document detailing how they should work (check it out here for JPA 2.0). So it happens then after all this was done, one of those potential 3rd parties who decided to implement the JPA specs was the Hibernate guys. And since JPA specs are very similar to the already existing (and fully implemented) Hibernate framework they decided to build it along side Hibernate. Thus in the Hibernate Framework you have both the original Hibernate API and implementation (which has nothing to do with JPA specs) and the JPA implementation. You can even use them both at the same times, though that's really not a good practice.
Now, the Oracle Java guys, after finishing the specs, also made an implementation of those themselves. They tend to do this with most of their specs APIs. This implementation is called EclipseLink and you can check it out here . Theoretically, your JPA project should work exactly the same if you switch your Hibernate-JPA implementation libraries to EclipseLink-JPA implementation libraries. In practice there are small differences.