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.
Related
We are going to write a service for which we are trying to evaluate technology stack. So as part of ORM we are thinking of using hibernate but from one of my colleague I came to know abt ebean. But we don't have any idea of ebean.
So my question is: Is there any disadvantage associated to hibernate, any salability or performance bottleneck? And what is the advantage ebean brings to the table?
What does Ebean bring to the table?
In short with Ebean it brings a full function ORM that is a lot easier to use and most importantly optimize (Well, it is easy but can also be done automatically via profiling).
A query language designed to optimise object graph construction via good support for Partial Objects and built in avoidance of N + 1
A "Sessionless" ORM ... architected to not have attach/detach semantics (So this makes it easier to use / fast to master).
Ebean now has SQL2011 History support and ElasticSearch integration. You could argue Hibernate has similar features.
Reference links:
ElasticSearch http://ebean-orm.github.io/docs/features/elasticsearch/
Automatic query tuning http://ebean-orm.github.io/docs/query/autotune
N + 1 http://ebean-orm.github.io/docs/query/nplus1
There are lot of issues with hibernate and basically any implementation of JPA in large and very scalable application. You should consider use another solution at all. Issues are well described in article Large Application Model issues and how model should look like in article Model for large applications.
As it is mentioned before, Ebean is sessionless ORM so you don't need to think about sessions. 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 but unfortunately such behavior may bring errors like "detached entity passed to persist".
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.
I need to build a reporting section of my site that consists of some decently complicated queries including things like UNION, GROUP_CONCAT, etc. JPA integration with my entities has maintained database independence so far. Currently the system uses MsSQL, but we want to be sure later we can switch to Postgres or MySQL if needed.
What's a good approach to take with these reports so that without too much work I can make it work on MySQL or Postgres?
The site also uses Spring
As I see it, your question is more or less "how can I make use of vendor specific features without becoming tied to that vendor?".
This result in not an easy answer; probably the most flexible would be stick to JPA and suck up the performance hit.
Other possibilities:
Define the reports as a component that publish a set of interfaces. Use CDI to inject the implementation related to your DB of choice
A variation of above, setup your own DAO interfaces for data access. Like another ORM framework that, being more specific, can have better performance. Build reports on top of that.
If your bussiness allows for it, chose a RDBM to work with for reports. During night time (maybe even on demand, if there is not too much data), dump your production database into it.
The best option is to use data access objects, one per database, each conforming to a common interface. Any client code can use the common DAO interface without needing to know about the underlying database.
With Spring it is easy to swap between the DAO implementation classes as a configuration option, e.g. if you have a CustomerDao interface that has Oracle and DB2 implementations, then use either:
<bean id="customerDao" class="my.package.customer.OracleCustomerDao"/>
or
<bean id="customerDao" class="my.package.customer.Db2CustomerDao"/>
If you want your SQL to work across multiple databases, then here's a plan you can follow:
Test your SQL across multiple databases
To get portability, you need to write portable SQL. The only way to ensure that your SQL is portable is to check it for portability.
If you stick to using standard SQL, then this should be fairly straightforward; you won't be able to use database-specific features, but there is a huge amount you can do without them (they're mostly syntactic sugar, or for stepping outside the relational model, which you hopefully won't need to do). If you've already strayed into using nonstandard SQL, then it may be very hard to get the point where you can do this, but if if you start off working in a disciplined way, i would be optimistic about your ability to stick to standards.
If you're working on SQL Server, the PostgreSQL would be a good choice for a second database to test against, as it's free, easy to set up, and very capable.
I am starting out writing java code and interacting with databases for my "nextbigthing" project. Can someone direct me towards the best way to deal with adding/updating tables/records to databases? Here is my problem. There is too much repitition when it comes to DB code in java. I have to create the tables first (I use mysql). I then create classes in Java for each table. Then I create a AddRow, DeleteRow, UpdateRow and Search* depending on my need. For every table, every need creating this huge ass sql statement and the classes all seems like a huge waste of my time. There has to be a better, easier, more efficient way of doing things. Is there something out there that I do not know that will let me just tell Java what the table is and it automatically generate the queries and execute them for me? Its simple SQL that can be auto generated if it knows the column names and DB table inter dependencies. Seems like a very reasonable thing to have.
Check out Hibernate - a standard Java ORM solution.
User hibernate for mapping your classes to Database.
Set its hbm2ddl.auto to update to avoid writing DDL yourself. But note that this is not the most optimal way to take it to production.
Consider using Hibernate:
https://www.hibernate.org/
It can create java classes with regular CRUD methods from existing database schema.
Of course there is a much better way !
You really want to learn some bits of Java EE, and in particular JPA for database access.
For a complete crash course on Java EE, check out the Sun the Java EE 5 tutorial.
http://java.sun.com/javaee/5/docs/tutorial/doc/
Part 4 - Enterprise Beans
Part 5 - Persistence (JPA)
Then you want to try Hibernate (for instance) which has an implementation of JPA.
This is for Java 5 or later.
If you are still in Java 2, you might want to try Hibernate or iBatis.
You can also try iBatis, if you want control over SQL. Else JPA is good.
You can also try using Seam Framework. It has good reverse-engineering tools.
There is also torque (http://db.apache.org/torque/) which I personally prefer because it's simpler, and does exactly what I need.
With torque I can define a database with mysql(Well I use Postgresql, but Mysql is supported too) and Torque can then query the database and then generate java classes for each table in the database. With Torque you can then query the database and get back Java objects of the correct type.
It supports where clauses (Either with a Criteria object or you can write the sql yourself) and joins.
It also support foreign keys, so if you got a User table and a House table, where a user can own 0 or more houses, there will be a getHouses() method on the user object which will give you the list of House objects the user own.
To get a first look at the kind of code you can write, take a look at
http://db.apache.org/torque/releases/torque-3.3/tutorial/step5.html which contains examples which show how to load/save/query data with torque. (All the classes used in this example are auto-generated based on the database definition).
Or, if Hibernate is too much, try Spring JDBC. It eliminates a lot of boilerplate code for you.
iBatis is another good choice, intermediate between Spring JDBC and Hibernate.
It's just a matter of using the right tools. Use an IDE with tools to autogenerate the one and other.
If you're using Eclipse for Java EE and decide to head to JPA, then I can recommend to take benefit of the builtin Dali plugin. There's a nice PDF tutorial out at Eclipse.org.
If you're using Eclipse for Java EE and decide to head to "good ol" Hibernate, then I can recommend to take benefit of the Hibernatetools plugin. There's good reference guide out at Hibernate.org.
Both tools are capable of reverse-engineering from a SQL table to fullworthy Javabeans/entities and/or mapping files. It really takes most of boilerplate pains away. The DAO pattern is slightly superflous when grabbing JPA. In case of Hibernate you can consider to use a Generic DAO.
We've been implementing Hibernate recently as a replacement for JDBC.
What I like is not having to constantly write SELECT, UPDATE, INSERT statements and the associated PreparedStatement and ResultSet code.
However we've been struggling with random bizarre behavior (example A) which I find hard to understand and resolve due to all the different configuration/feature options and the associated Hibernate behavior. I find some of the features like caching, lazy loading, etc, etc very cool but way more than I need - and ultimately confusing.
Is there a better middle ground for someone just looking to avoid the tediousness of JDBC but who doesn't need all the features of Hibernate?
not completely avoiding jdbc, but ... my suggestion is to use the jbdc support provided by spring framework. You still need to write your select, update and inserts, but spring nicely wraps it so you usually don't care about the result set, closing connections, cleaning up your code and such.
Have a look at this chapter from the spring documentations to see the details. You can create an entire dao layer that appears just like the hibernate dao layer, but the internal implementation is different. The RowMapper interface lets you handle the conversion from result sets to objects very nicely. Overall it provides a clean separation of concerns.
(another alternative is to use iBATIS for lightweight O/R mapping, or at least to keep your sql queries outside of Java code).
How about using Hibernate (or TopLink) as a JPA provider. IMO I find the JPA annotation-based approach to doing ORM a lot easier to understand / implement than Hibernate directly - and you can always drop down and do 'difficult' stuff with Hibernate directly.