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.
Related
We have an application thats already running for a long time. Now we are migrating it to Spring and possibly using Hibernate or any other ORM.
But we caught up with a question. Is it not recommended / bad idea to use Hibernate for the already existing Database and model the object around Schema?
Most people advocate NOT using Hibernate and instead of go with some other ORMs like iBatis. But in our company, all are proponents of Hibernate.
Any experiences?
I would say that it's irresponsible to choose Hibernate, iBatis, or anything else without knowing your requirements.
If you don't have a solid object model, I'd say that Hibernate is a terrible choice.
If you use stored procedures as the interface to your database, I'd say that Hibernate is a terrible choice.
If you don't like the dynamic SQL that Hibernate generates for you, I'd say that Hibernate is a terrible choice.
Get it? Knee-jerk reactions like the ones from those Hibernate proponents aren't a good idea.
It might be that iBatis or Spring JDBC template is a better choice than Hibernate. You ought to become more informed about that decision and make it for your application rather than blindly listen to a mob.
You don't have to be all or none about it, either. It's possible to implement part of your solution with one technology and the rest in another.
I'd recommend making your persistence layer interface-based so you can swap implementations without affecting clients.
I recommend looking at SansORM (a NoORM object mapper). It is designed for SQL-first development, which fits well with retrofitting an existing schema.
Hibernate works well if you can model your database under your objects.
Vice versa, you are likely to get the database model as your your domain model. You need to evaluate how distant those two models are, otherwise you are going to map the database => ORM objects => your domain model. I would avoid that.
If I want to skip the ORM part, I find myself quite happy with JDBI which I prefer over Spring JDBC Template
As others have pointed out an ORM is only a good choice if your database is not far from an object model.
If that is the case then an option would be Hibernate through JPA for two resons:
Netbeans has a tool to generate JPA Entities from an existing database. This entities are not dependant on Netbeans so you could use a different IDE after the initial reverse engineering.
Spring Data JPA can avoid writing trivial queries and focus on the hard ones.
every website I can find seems biased to praised objectdb over hibernate and mysql. Example, http://www.jpab.org/ObjectDB/ObjectDB/server/Hibernate/MySQL/server.html.
Are there any disadvantages to using objectdb instead of hibernate and mysql for java web services? I am of course using JPA.
You mean are there advantages and disadvantages of using an ODBM against an RDBMS ? There are ample refs on the web that address that.
With particular respect to JPA, it is designed around RDBMS syntax, and so it is likely that some query sintaxis will not be fully supported in an object datastore (whether ObjectDB or any other). This may mean that some queries either throw an exception or evaluate in-memory (and that may mean speed). On the other hand it may be quicker at some persistence ops. Obviously you will not get anything like the number of people available who know about that datastore if you have problems, whereas with MySQL there are many thousands.
Also there are many JPA implementations available for persisting to MySQL, and they all have their own advantages and disadvatanges. Hence this questions is way too open ended, and is just going to search for personal opinion rather than anything specific fact based
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 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.
How does ORM work? Are objects serialized into BLOBs?
In Java, is JDO still the way to go for this? What else is available? Seems like there was a lot of talk of EJB, direct object serialization, and JDO.
To answer your first question, here is an extract from Hibernate in Action, that says that there are various ways to implement ORM:
Pure relational
The whole application, including the
user interface, is designed around the
relational model and SQL-based
relational operations. This approach,
despite its deficiencies for large
systems, can be an excellent solution
for simple applications where a low
level of code reuse is tolerable.
Direct SQL can be fine-tuned in every
aspect, but the drawbacks, such as
lack of portability and
maintainability, are significant,
especially in the long run.
Applications in this category often
make heavy use of stored procedures,
shifting some of the work out of the
business layer and into the database.
Light object mapping
Entities are represented as classes
that are mapped manually to the
relational tables. Hand-coded SQL/JDBC
is hidden from the business logic
using well-known design patterns.
This approach is extremely widespread
and is successful for applications
with a small number of entities, or
applications with generic,
metadata-driven data models. Stored
procedures might have a place in this
kind of application.
Medium object mapping
The application is designed around an
object model. SQL is generated at
build time using a code generation
tool, or at runtime by framework code.
Associations between objects are
supported by the persistence
mechanism, and queries may be
specified using an object-oriented
expression language. Objects are
cached by the persistence layer. A
great many ORM products and homegrown
persistence layers support at least
this level of functionality. It’s well
suited to medium-sized applications
with some complex transactions,
particularly when portability between
different database products is
important. These applications usually
don’t use stored procedures.
Full object mapping
Full object mapping supports
sophisticated object modeling:
composition, inheritance,
polymorphism, and “persistence by
reachability.” The persistence layer
implements transparent persistence;
persistent classes do not inherit any
special base class or have to
implement a special interface.
Efficient fetching strategies (lazy
and eager fetching) and caching
strategies are implemented
transparently to the application. This
level of functionality can hardly be
achieved by a homegrown persistence
layer—it’s equivalent to months or
years of development time. A number
of commercial and open source Java ORM
tools have achieved this level of
quality. This level meets the
definition of ORM we’re using in this
book. Let’s look at the problems we
expect to be solved by a tool that
achieves full object mapping.
ORM = Object Relational Mapping, attributes of the objects are mapped to columns in the realational database. That mapping is arbitrary, so that could be done to blobs, in practise what is most useful tends to natural mappings - Strings to Varchars, int to integers etc.
JPA is the place to look for a standard for ORM. JPA replaces the EJB CMP approach, which was found to be cumbersome. JPA allows you to express the mapping as Java annotations and also allows the mappings to be specified in configutration files, when supporting multip[le databases the latter can be useful.
JPA has a query language so that you can construct queries against object attributes.
JPA is supported by the major App Server vendors and also by products such as Hibernate.
I found JPA pretty nice to work with, more so than EJB CMP.
I would recommend still using EJB Session Beans facades for transaction mamangement and security - the annotation-based approach makes EJB 3 way easier to use than EJB 2, minimal coding overhead.
JDO is actually standard ORM too, and provides a more complete a specification than JPA (1 + 2). JPQL is more focussed on RDBMS concepts and hence mimics SQL. JDOQL follows Java syntax so is more object based. Depends if your app is ever considered to go away from RDBMS. If so then JPA is not the way to go. If it is solely for RDBMS then JPA is definitely a consideration.
Whether objects are serialized into BLOBs depends on your configuration. You can do that for complex object types if you wish, but then they won't be queryable. If you instead persist them in a native form then you can also query them, leading to more efficient apps.
--Andy (DataNucleus - JDO and JPA persistence)