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.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
We have been using JDBC for a very long time in our web applications. The main reason we used it is because we have 100% control over the code, sql and fix things by our hands. Apart from that we used triggers inside the database, and the database is developed separately by DB experts.
However many now recommend using Hibernate so we also thought about using it. But, we found the below issues.
Hibernate cannot connect with an "Existing" database. It always try to create a one of its own.
Our database might access by same application which is in different platforms (cloud, server, VPS, Personal Computer). Hibernate can make problems because of its caching in this situation.
We never like to give the "table creating work" to the java code. We create tables manually, always.
We might have to use very long and complex SQL statements. Last time we used an statement with more than 150 lines, joining more than 20 tables. We doubt whether we will face troubles in this when it comes to Hibernate.
Our SQL code is nice and standard. Hibernate generated code seems to be bit dirty for us.
We always use MySQL. Never use any other DB.
The application we create require max security, related to medical. If at least one data record is leaked, we are done.
There are lot of foreign keys, Primary Keys, Composite Keys, Unique Keys etc etc in database. In forums, some complained that Hibernate messed with those.
We decided to try hibernate because some people claims, "Are you Software Engineers? You are using already dead JDBC !!. "
Considering these, please let me know whether the above points are actually true (as I said, I got to know them via googling, discussion etc) or not. And, what are the pros and cons of Hibernate VS Java JDBC?
Answering issues listed above:
1. Hibernate cannot connect with an "Existing" database. It always try to create a one of its own.
This is wrong. Hibernate can connect to an existing database, and it doesn't always try to recreate it. You just should turn of parameter like hbm2ddl. auto.
2. Our database might access by same application which is in different platforms (cloud, server, VPS, Personal Computer). Hibernate can make problems because of its caching in this situation.
Hibernate has an adjustable cache, so this is also not a problem.
3. We never like to give the "table creating work" to the java code. We create tables manually, always.
No problem. See p.1 above. Furthemore there are several convinient libraries for indirect table creation and update (e.g. liquibase) which can be used in couple with hibernate perfectly.
4. We might have to use very long and complex SQL statements. Last time we used an statement with more than 150 lines, joining more than 20 tables. We doubt whether we will face troubles in this when it comes to Hibernate.
You can always use direct JDBC calls and invoke native SQL queries via hibernate, if it is neeeded.
5. Our SQL code is nice and standard. Hibernate generated code seems to be bit dirty for us.
Again, if you have to invoke some logic complicated SQL code instead of hibernate auto-generated - you can do it.
6. We always use MySQL. Never use any other DB.
Not a problem at all. Hibernate has special MySQL dialect support: org.hibernate.dialect.MySQLDialect.
7. The application we create require max security, related to medical. If at least one data record is leaked, we are done.
Security issues aren't related to ORM techniques. Hibernate is just logical and convinient object-oriented layer between pure database JDBC calls and programmers tools. It doesn't influence somehow on common net security.
Hibernate is a great tool and you'll find plenty of documentation, books, and blog articles about it.
I will address all your concerns:
Hibernate cannot connect with an "Existing" database. It always tries to create one of its own.
Hibernate should use a separate database schema management procedure even for integration testing. You should use an incremental versioning tool like FlywayDB to manage your schema changes.
Our database might access by same application which is in different platforms (cloud, server, VPS, Personal Computer). Hibernate can make problems because of its caching in this situation.
You don't have to use the 2nd level cache, which uses 3rd party caching implementations. All caching solutions may break transactional consistency. The first level cache guarantees session-level repeatable reads and with the optimistic locking in place you can prevent lost updates.
We never like to give the "table creating work" to the java code. We create tables manually, always.
The DB should be separated from your ORM tool. That's a best practice anyway.
We might have to use very long and complex SQL statements. Last time we used an statement with more than 150 lines, joining more than 20 tables. We doubt whether we will face troubles in this when it comes to Hibernate.
Hibernate is great for write operations and for concurrency control. You still need to use native SQL for advanced queries (window functions, CTE). But Hibernate allows you to run native queries.
Our SQL code is nice and standard. Hibernate generated code seems to be bit dirty for us.
You don't need and you shouldn't probably use the hbmdll utility anyway.
We always use MySQL. Never use any other DB.
That's even better. You can therefore use advance native queries without caring for database portability issues.
The application we create require max security, related to medical. If at least one data record is leaked, we are done.
Hibernate doesn't prevent you from securing your database or the data access code. You can still use database security measures with Hibernate too. You can even use Jasypt to enable all sorts of security-related features:
advanced password hashing
two-way encryption
There are lot of foreign keys, Primary Keys, Composite Keys, Unique Keys etc etc in database. In forums, some complained that Hibernate messed with those.
All of those are supported by Hibernate. Aside from the JPA conventions, Hibernate also offers particular mapping for any exotic mapping.
We decided to try hibernate because some people claims, "Are you Software Engineers? You are using already dead JDBC !!. "
That's not the right argument for switching from a library you already master. If you think you can benefit from using Hibernate then that's the only compelling reason for switching from JDBC.
Using plain old JDBC, does not mean you are lacking in IT industry, rather Hibernate also uses JDBC in the underlying layer.
What advantages it gives us what we should look for.
1.) Cache Mechanism.
2.) Managing sessions, transactions etc.
3.) Reduce efforts in writing queries, more utilities of hibernate like Query API, Criteria API, HQL
The questions that you have raised are more or less covered in Hibernate docs.
Also there are lot more caching strategy available ehcache, infinispan, depends on the server we are deploying, JBOSS, Weblogic, Tomcat etc. ++ environment like cloud, distributed cache etc.
Hibernate still provides you with option of turning off automatically creating schema and pointing to the one create by you.
Here are the quick answers that I know
1) You can connect to an existing database. But yeah as stated here
If you don't have a solid object model, I'd say that Hibernate is a
terrible choice.
2) As you database is been accessed from different applications so you can maintain locks. On-the-other-hand you can trun-off caching as done here.
3) You can create tables manually and connect it using .hbm.xml file.
4) You can use any type of query in hibernate like simple SQL queries criteria.
5) You can directly use SQL code in Hibernate, if you want. Other option is to use criteria.
6) Hibernate is NOT DB specific. You can go for any Database and connect it with hibernate.
7) Using locks and giving rights in database you can maintain security.
8) Agreed that foreign keys are messy in Hibernate If You Donot Handle It Well. So Use OO approach and maintain cascades well, then Hibernate will be good choice.
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".
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 spent all of yesterday reading various articles/tutorials on Hibernate and although I am blown-away by how powerful it is, I have one major concern with it.
It seems that the standard practice is to allow Hibernate to design/generate your DB schema for you, which is a new and scary concept that I am choking on. From the tutorials I read, you just add a new entity to your hibernate.cfg.xml config file, annotate any POJO you want with #Entity, and voila - Hibernate creates the tables for you. Although this is very cool, it has me wondering about a handful of scenarios:
What if you already have a DB schema and the one Hibernate wants to generate for you does not conform to it? What if you have a crazy DBA that refuses to budge on the pre-defined (non-Hibernate) schema?
What if you have reference tables with tens of thousands of records in it (like all the cities in the world)? Would you have to instantiate and save() tens of thousands of unique POJOs or is there a way to configure Hibernate so it will honor and not overwrite data already existing in your tables?
What if you want to do perf tuning on your schema/tables? This includes indexing, normalizing above and beyond what Hibernate creates automatically?
What if you want to add constraints or triggers to your tables? Indexes?
I guess at the root of this is the following:
It looks like Hibernate creates and forces a particular schema/config on your DB. I am wondering how this agenda will conflict with our platform standards, our DBA philosophies, and our ability to perf tune/tweak tables that Hibernate interacts with.
Thanks in advance.
I think you're attributing too much power to Hibernate.
Hibernate does have an idiom that may influence database implementation.
Hibernate does not generate a schema for you unless you ask it to do so. It's possible to start with an existing schema and map it to Java objects using Hibernate. But it might not be possible or optimal if the schema conflicts with Hibernate requirements.
If the DBA won't budge - as they shouldn't - or Hibernate can't accomodate you, then you have your answer: you can't use Hibernate.
Your DBA might consent, but your app might find that the dynamic SQL that's generated for you by Hibernate isn't what you want.
Fortunately for you, it's not the only game in town.
I don't think implementations have to be all or none. If you use simple JDBC to access reference data, what's the harm?
Database design considerations should be independent of Hibernate. Constraints, triggers, normalization, and indexes should be driven by business needs, not your middleware choices.
If you don't have a solid object model, or the schema can't accomodate it, then you should reconsider Hibernate. There's straight JDBC, stored procedures, Spring JDBC, and iBatis as alternatives.
Hibernate comes with a default way to map objects to tables - like several tools/libraries, it favours convention over configuration for simplicity.
However, if you want to map the entities to database tables differently, you can explicitly tell Hibernate how these are mapped (from simple attributes such as changing the table name, through to redefining the foreign-key relationships between related entities and how this is persisted).
If you do this correctly, you don't need to instantiate and save existing data, as this would be pointless - the database already contains the information about the entities in exactly the form that Hibernate understands. (Think about it - to load and then immediately save an entity should always be a no-op, and so can be skipped altogether.)
So the short answer to your question is "no". If you don't care for designing tables, you can let Hibernate adopt a reasonable default. If you do want to design your schema explicitly though, you can do this and then describe that exact schema to Hibernate.
As someone who's worked on java and hibernate in the enterprise for a long time, I have seen very few projects which use this capability. You'll see some build tools and other things do this, but for a real enterprise app, i've never seen this.
Most DBA's won't let the application user create tables. They rely on a privileged user to do those things, and the user that the app connects as would have r/w privs on the data but not the schema itself.
As a result, you write the SQL yourself, and you do the hibernate mappings to match. It doesn't mean your object design won't influence your SQL, but you should still always create your schema upfront.
No. You can use hibernate tools to generate the entities from existing database.
There are 2 ways you can go about in using Hibernate. If you have good DBA or database designer, then it is better to design the database and then map it into hibernate.
On the other hand if you don't have DBA and have good developer then let Hibernate generate Database for you.
The concept behind Hibernate is to map Database and the Objects. So it is called as ORM (Object-Relational Mapping) tool.
Read here for Object Relational Impedance.
This is the preferred way for a quick'n dirty prototype or a simple tutorial, but it's far from being the preferred way for any production application. I largely prefer designing the database independently, using scripts to generate the schema, tables, views, indexes, etc., and map the schema to entities.
As long as the mapping finds the tables and columns in the database, everything is fine.
As soon as you have data in your database and the schema must change, you'll have to write migration scripts anyway. You can't just drop everything and restart from scratch. The tutorials are written for developers starting with Hibernate and who must discover Hibernate as quick as possible, without dealing with complex SQL scripts.
What if you already have a DB schema ...
I don't know where you get that impression. Hibernate can use existing schema. It is quite flexible.
What if you have reference tables ...
Make the relationship LAZY, and it won't load automatically. Only changed object will be saved.
What if you want to do perf tuning ...
Just don't use the generated schema. It is just a starting point. You can customize as you need.
What if you want to add constraints or triggers to your tables? Indexes?
Some as above.
You can use hibernate with an existing database schema.
You can use various annotations to map to existing tables and columns, for example:
#Table(name = "dbschema.dbTable") - should be placed before your class file to map it
#Column(name = "colName") - to map a column
Just be sure that the hibernate is configured with this option:
hibernate.hbm2ddl.auto=update
If you set this to create it will create the schema, so do not do this in your case.
Use hibernate/jpa when appropiate. A common practice when designing apps is to extract the draft and alter it manually after needs (indices etc). However, it will be a pain for you if you change the db layout from hibernate way to do things. Lots of the beauty of JPA will be lost. For tasks which require heavy performance tuning and full control - just go for reguar jdbc.
Some answers:
A. It is possible to add an index annotation : see the table annotation.
B. If you have reference tables, you may choose to have lazy fetching or eager fetching (i.e - if your tables represent a person and a its books - whether to load a person without its book, or with its books)
C. Hibernate can be used to work on existing schema. The schema might not be trivial to work with , but as other have said, you should design db only according to business needs, and not according to framework conventions
D. I would like to encourage you also to read what hibernate does "under the hood" - it uses lots of usage of proxies, which hurts performance, you must understand well the scope of session , and the usages of 1st level and 2nd level cache .
E. Following what I wrote at section D - working with triggers will cause your DB to change "under the hood" when it comes to hibernate. Consider a case where updating a record will create (using a trigger) an entry in some archiving table , and let's say this table is also annotated via hibernate - your hibernate caching will not be aware of the change that happend outside of the application scope.
F. It is important to me to state that I'm not against Hibernate, but you should not use it for all solutions, this is a mistake I did in the past. I now work with Spring-JDBC and I'm quite pleased (for our application needs it will be hard to use Hibernate, and I assume we will consider this only in the case we need to support more than one DB flavor).
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.