Today I was trying to create a application using Hibernate as ORM. So while creating I had a doubt. What is the best practice to use, Hibernate mapping file (.hbm file) or annotations ? What are the pros and cons of it ? Please help me in understanding.
there is no functional difference. You can do (almost) the same things with both approaches
xml files were used before Java had annotations (added in 1.5), so they can be considered an outdated way of mapping
it is generally preferred to use JPA annotations rather than hibernate-specific ones; if using xml - there is a JPA xml format, which should be preferred to hibernate native one
The question is what is your taste - both ways can do (mostly) the same, the difference is how to write.
With annotations you have the Java member variable/getter and the mapping directly together at one place.
Xml mapping files give a better overview over the table and its mapping.
In my opinion xml mapping files help for a better design of the database and application. Annonations tend to force the direction Java class -> mapping -> database table, which is the wrong direction (the database always should be designed first - changing database tables later is a lot of effort - most performance leaks are in a bad database design - Java classes easily can be changed any time).
There if one functional advantage of xml files: If you have different databases with structural differences, for example one Oracle database and one MySQL database, perhaps some differences in table names and data types, then for porting your application from one database to another you only need to write some new mapping files. You do not need to change a single line of Java code. This is not possible with annotations.
I prefer to use xml mapping files. That is my taste.
One good use-case for using the XML approach is if you are persisting objects that have been generated by another utility and therefore cannot be annotated.
Other than that, I would use annotations as it tends to lend itself to a cleaner implementation and you're less likely to introduce bugs by misspelling property names.
This is how it says in "TUTORIALS POINT"
"If you going to make your application portable to other EJB 3 compliant ORM applications, you must use annotations to represent the mapping information but still if you want greater flexibility then you should go with XML-based mappings"
For me I would prefer XML configuration file, than annotation. Because then we can do changes, with minimum code changes.
Annotations are based on the principle of convention over configuration:
http://en.wikipedia.org/wiki/Convention_over_configuration
while xml files are just configuration.
There are many discussions about using annotations vs using configuration.
stackoverflow link
From my point of view, I prefer annotations because it is easier to write and to maintain.
Annotations are developed with java language and java developer easy to learn when compared with XML. And one more point in real time table names and column names are fixed 99%, so no need to change java code also
but if you want to change table names and column names frequently you will move with XML
finally cfg.xml file is manadatary because database may change.
Related
I having hard time understanding importance and benefits of Annotations and so have two questions regarding them:
What are the benefits of Annotations as compared to XML Configuration?
How do Annotations work internally?
Is it fair enough to say that annotation binds application tightly whereas with XML Configuration Application is loosely coupled?
Would appreciate pros and cons comparison with XML Configuration with example so that it would be much more helpful for me to understand.
Regards.
For your 1st question,
Xml configuration versus Annotation based configuration
Personally, I feel, there are two criteria's
Can annotations simplify the metadata ?
If annotations do not reduce the amount of metadata that you have to provide (in most cases they do), then you shouldn’t use annotation.
Can changes to the metadata break behavior in your application?
If not, then you can feel comfortable applying the change while the system is running in production. External config files are the best place for the metadata in this case because you don’t want to have to recompile your code to make the change.
For your 2nd question,
How Do Annotations Work?
Important Links :
What are annotations and how do they actually work for frameworks like Spring?
Both annotations and XML descriptors are used to describe some metadata on top of regular code. The primary difference is that in case of annotations you only have to deal with one file which includes code and metadata. It is also a big advantage of annotations as it reduces number of moving parts and increases productivity.
On the other hand, the drawback of annotations is that they bind together the code and the system or framework that operates using those annotations. That makes it harder to separate those in future.
For example, if you use Hibernate Annotations, you bind your model objects with Hibernate. If you choose to switch to different framework, you will have to rip out Hibernate annotations from the code.
But practically, it's not that likely that you will be changing frameworks that often. There are usually many other reasons why changing framework on existing code base may be hard. So often annotations is a good choice.
As to how they work, annotations are a part of the language and are processed by compiler and other tools and, depending on retention, can be included in produced bytecode for use at runtime. Ultimately, it's up to consumer to decide on how to use annotations.
To answer the first question, IMO the greatest benefit is the potential for compiler integration. I can write an annotation processor that can validate some semantics related to the application of the annotation. That kind of compile-time checking is not possible (or would at least be way more difficult) if the same information was instead part of an XML document.
To answer the second question, annotations don't really "work" internally, per se, in the sense that they don't have any inherent execution semantics. They are source level entities that may or may not be retained in the classfile. The can be processed during compilation of the source, and if they were retained in the classfile, can be accessed via reflection.
I'm working on a medium-sized project in Java (GWT to be precise), and I'm still in the process of deciding what ORM to use.
I just refuse to write SQL queries unless utterly and completely necessary (not the case :D)
I want to use ONLY annotations, no XML configuring [except database location, username, etc], and I DON'T want to create any tables or define them. I want this to be done by the framework completely.
Call me lazy, but I like Java/GWT programming, not creating tables and coping with that sort of things, and it's a plus in my assignment if I actually use an ORM :D
I've considered so far:
Hibernate with annotations: I've found little documentation to get started from ground using this. I've found little examples and alike. It's as if they didn't actually want you to use 100% annotations.
DataNucleus
JDO: It seems interesting, I'd never heard of DataNucleus up to until this week, but it seems extremely mature, and I actually discovered it because Google uses it in GWT, so that's a good sign. I also like the fact that they mentioned I don't need to define any tables or columns, though I think hibernate can achieve this as well. I actually enjoyed reading though their documentation (though I haven't finished yet), something quite opposite to hibernate.
JPA I'm not totally sure if DataNucleus/JPA can work with annotation-only configuration, though I might need to take a deeper look into the documentation.
As you might guess, I'm quite inclined to JDO... but it'd be nice to hear what people who've used it have to say vs the other alternatives, and if i'm missing some very important point here.
Edit 1: I know I'll need to XML the database location/usr/pwd, I meant I don't want to use an XML to configure the mapping or database schema.
JPA (1 and 2) is pretty much XML free, depending on how it's packaged. You most certainly don't need it for the schema. It also supports annotations for details when the tables are generated.
The only issue with these is that while they can create a database, they're a DB MAPPING tool, not a DB DEFINITION tool. Specifically, most won't allow you to create the arbitrary indexes that you may well need to get the DB tuned properly to your queries.
But other than that, JPA should fill your needs, and it has a lot of implementations (Hibernate is just one implementation).
This is a self publicizing but I'm been working for a while on a simple Java ORM package called ORMLite. I wanted something much less complicated than hibernate but without writing SQL directly. It's completely annotation based and currently supports MySQL, Postgres, Derby, and H2. Adding other database would be simple if I have access to a server. It is completely annotation based and can create (and destroy) tables.
http://ormlite.com/
It has pretty flexible QueryBuilder and table paging. Joining is, however, not supported.
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 9 years ago.
Improve this question
I've observed the strange fact (based on the questions in the hibernate tag) that people are still actively using xml files instead of annotations to specify their ORM (Hibernate/JPA) mappings.
There are a few cases, where this is necessary:
you are using classes that are provided, and you want to map them.
you are writing an API, whose domain classes can be used without a JPA provider, so you don't want to force a JPA/Hibernate dependency.
But these are not common cases, I think.
My assumptions are:
people are used to xml files and don't feel comfortable / don't want to bother learning to use the annotation approach.
Java pre-1.5 is forced upon the project and there is nothing to do about it
people don't know that annotations are a full-featured replacement of xml mapping.
legacy systems are supported and hence changing the approach is considered risky
people fear that mixing annotations (meta-information) with their classes is wrong.
Any other possible explanations?
The domain layer and the persistence layer are considered by some to be separate concerns. Using the pure XML approach keeps the two layers as loosely coupled as possible; using annotations couples the two layers more tightly as you have persistence-related code embedded in the domain code.
Lack of overview of what's been mapped. You need to dig in the source code.
people don't know that annotations are
a full-featured replacement of xml
mapping.
Ah, but they're not. Three cases off the top of my head (there are probably more) you can't do (well) with annotations:
Use formula as part of association key (admittedly, rather esoteric).
Join-via-subselect - #Loader is not an adequate replacement. Not too common but quite useful. Envers provides a viable alternate approach.
Losing column order for schema generation. This one's an absolute killer. I understand why it's done this way, but it still annoys me to no end.
Don't get me wrong, though - annotations are great; doubly so when they're coupled with Validator (though, again, #3 above kills the buzz on this one). They also provide certain aspects of functionality that XML mappings do not.
Using XML to complement the annotations, where environment or system specific configuration is needed.
Some information is carried nicely in annotations, such as the cardinality of relationships between entities. These annotations provide more detail about the model itself, rather than how the model relates to something else.
However, bindings, whether to a persistence store or XML or anything else, are extrinsic to the model. They change depending on the context in which the model is used. Including them in the model is as bad as using inline style definitions in HTML. I use external binding (usually—though not necessarily—XML) documents for the same reasons I reference an external CSS.
I initially found the annotation syntax very weird. It looks like line noise and mixes in with where I usually put comments. It's vastly better than dealing with the XML files though, because all of the changes are in one place, the model file. Perhaps one limitation of annotation is possible collision with other annotations, but I haven't seen that yet.
I think the real reason that it isn't used more is that it isn't really considered the default. You have to use an additional jar file. It should be part of core and the XML approach should be the optional one.
I've switched to annotations, but sometimes I miss the XML mappings, mainly because the documentation was so much more comprehensive, with examples of many scenarios. With annotations, I stick to pretty basic mappings (which is great if you control the data and object model), but I've done some very complex things in the XML that I don't know if I could replicate in the annotations.
So if you want to deploy your class to multiple datastores. And you want to annotate column definitions into it do you ? Different datastores have different conventions etc and using XML is the only sane place in that situation, being able to have one for MySQL, and one for Derby, and one for Oracle or whatever. You can still put the basic persistence/relation annotations in if you wish, but the schema-specific stuff would go into XML in that case.
--Andy (DataNucleus)
I have a new one : http://www.summerofnhibernate.com/
Very nice screencast series not yet covering annotations. I have written some apps with it to learn the basics, not for my job but out of curiosity, but never migrated to annotations yet. The series where suggested as still relevant on SO. I still will migrate to annotations if I have some more spare time but for the time being I could be one of the persons asking questions about it.
I worked on a project where the database would change very frequently and we have to regenerate the java files and configuration files each time it happens. Actually we do not use all the relationships and configurations generated by hibernate tool. So basically we use the tool and then modify/tweak them.
So when you want to modify/tweak the default configurations, it is easier to do in the XML file in comparison to doing it through annotations.
I feel that it makes the code much more readable if we donot use Annotations.Use of Annotations can really help if the configuration info changes frequently, but take the case of web.xml, how many times does the info in that change, so why use annotations for Servlets.
We continue to use XML because typically for deployed sites, getting a patch (binary code) approved for installation takes time that you may not have. Updates to ASCII files (e.g. xml files) are considered configuration changes and not patches...
t
I currently use JPA annotations only, but I really don't like that I'm polluting my entity classes with so many ORM details which really aren't relevant to their behavior (e.g. table name, id generation strategies, join columns...).
I see that DataNucleus recommends putting ORM-related annotations in XML instead (those colored in pink), but I haven't seen any other implementations recommend this and JPA doesn't seem to separate annotations into these two groups (I think JDO does).
Is anyone using annotations+orm.xml in this way, and what are your experiences?
Will it remove some of the pollution from my entity classes, or will I run into problems?
The biggest issue we've faced on a semi-regular basis is that if you want to change your persistence mapping in any way using annotations alone you need to recompile and redeploy.
Using orm.xml affords you a degree of abstraction which can make reconfiguration a little more straight forward, and achievable with technically the same code base (eg you're sure that a line of code hasn't snuck into what you're recompiling/redeploying).
You can use both annotations and configuration - which is the environment I'm now working with - classes are annotated with functional type persistence metadata (i.e. foreign keys, joins, etc - things which have a code level representation) while irrelevant information (i.e. table/column names) are stored in configuration files.
We're still trying to develop some clear heuristics around when we use one configuration mechanism over another, but we're getting there.
JPA entities being just Java Beans (classes defining getters and setters) with optional supporting code (constructors, hashCode, equals, named queries, copy methods, what else?) could hardly be considered polluted even with all types of JPA annotations included.
The real purpose of splitting metadata between Java annotations and xml would be simplification and optimization of deployment policies. The price that you will incur is two-fold:
enforcement of development
policies regarding what metadata
belongs to which place and
cross referencing java and xml when creating
and especially maintaining metadata (more or less but always inconvenience).
Both are rather serious considerations when working in average to large size development team.
If recompiling for database changes presents a significant challenge in your deployment process then it sounds as a reasonable approach. But the price will be more complex development environment and process and maintenance policies.
I am currently using Hibernate Tools 3.1; I customized naming convention and DAO templates. The database (SQL Server 2005) in early development phase and I'm in charge of rebuilding the mappings, entities, DAOs, configuration, whatever. Each time I have to reverse-engineer the tables and so I lose every customization I made on the mappings (*.hbm.xml files) like adjusting the identity columns, picking the fields used in equals and toString. I was considering to write the diff XML in a file and the "merge" that onto the generated mapping (see my related question) but I was wondering... is there any best practice/tool for dealing with these annoying, unavoidable, critical tasks?
I'd strongly recommend against continual reverse engineering. Reverse engineering is a great one time thing, but changes need to be managed as changes to both the hbm and the database.
We use migrations to manage db changes, and we include the associated changes in the hbm. If Hibernate has it (I believe it does) you may want to look into annotations instead of an hbm, they can be quite a bit easier to maintain.
This is two and a half years late, but I'll offer a dissenting opinion. You should be able to make any customizations you need to the mapping files through the hibernate.reveng.xml file or a custom ReverseEngineeringStrategy. For the classes themselves, you should always generate to base classes and extend them with classes containing custom code.
For example, generate com.company.vo.generated.CustomerGenerated and extend it with com.company.vo.custom.Customer. Code generation should overwrite all classes in the generated package but never in the custom package (although you can have Hibernate Tools generate these custom classes in the target directory so that you can copy and paste blanks into the custom directory as needed). This way you can override methods for equals, toString, etc in the custom classes and not lose your changes when you regenerate. Also note that the best practice is to not check in generated code into SCM.
There are some great examples on this site of how to achieve this using Maven, the Hibernate3 plugin, and the build helper plugin. Most of these have very helpful answers by Pascal Thivent. This method is working beautifully for me, and while there is a bit of a learning curve it's a wonderful thing to be able to propagate database changes to the app with a single Maven command.