We are glad to announce that the new Hibernate ORM User Guide has become the default Hibernate 5.1 reference documentation. This process was started last summer, and it was one of the primary goals of the Hibernate 5 project version.
Previously, all the documentation was written in DocBook, and we wanted to move away to a more human-friendly format. Thanks to Dan Allen and the Asciidoctor community, we now have a tool to write technical documentation where the actual content doesn’t get lost in a myriad of XML markup tags.
All the examples are embedded from unit tests which are, of course, available on GitHub. This way, we ensure that all code snippets are valid and relevant in the future as well (removing a deprecated class will trigger a test failure, and we can immediately update the broken example).
The previous documentation was featuring many XML-based examples which were no longer relevant for the vast majority of our users. Because it is very common to use Hibernate as a JPA provider, most examples are written according to the Java Persistence API specifications but, since Hibernate is more than a JPA provider, we also feature Hibernate-specific examples which cover use cases that are not supported by the JPA standard.
As previously stated, the User Guide is not finished yet. In the near future, we are going to enhance the following sections as well:
Hibernate support for calling stored procedures,
Migrating Hibernate Envers examples to unit tests,
A new section about Hibernate Spatial.
Enjoy reading it and we are looking forward to getting your feedback!
Starting this year, we are hosting a series of articles focused on the Hibernate community. We share blog posts, forum and StackOverflow questions that are especially relevant to our users.
We are happy that Hibernate 5.1 is ready. The new User Guide still needs a few site-related changes in order to make the switch, so stay tuned!
Ondrej Mihályi made a summary of the differences in JPA entity locking modes.
Lorenzo Dee wrote an article about JPA pitfalls.
Javin Paul describes why JPA and Hibernate entity classes shouldn’t be final.
I wrote an article about enabling bytecode enhancement in Hibernate 5.
Eugen Paraschiv wrote a very detailed article about auditing entity changes, comparing JPA callback annotations with Hibernate Envers and Spring Data JPA Auditing.
The guys at Plumbr have raised awareness of how the MySQL JDBC driver handles database-generated warning messages. We created a JIRA issue for this, and we’re discussing various possibilities for handling it without affecting other database drivers which are more efficient in this regard.
I wrote an article about the
AUTO flush mode handling strategies employed by the Hibernate implementation of the Java Persistence API and the Hibernate native API.
WildFly 10 has just been released with support for Hibernate 5.
Thorben Janssen recorded a video explaining the first-level cache.
A very interesting project is Apache Trafodion, which aims to build a transactional SQL engine on top of Hadoop. We’d like to thanks the Trafodion team for writing a Hibernate Dialect, therefore making it possible to access Hadoop from a Hibernate data access layer. Give it a try and let us know what you think.
Thorben Janssen wrote an article about calling native SQL queries from JPA.
Romain Manni-Bucau demonstrates how you can integrate JPA pagination with Java 8 Streams.
Happy New Year, everyone!
Starting this year, we are going to host a series of articles focused on the Hibernate community. We are going to share blog posts, forum and StackOverflow questions, that are especially relevant to our users.
Thorben Janssen, who regularly writes about JPA and Hibernate topics, has summarized the most typical logging configurations in a Hibernate Logging Guide.
For our Portuguese readers, Rafael Ponte has written a very interesting article about bidirectional relationships and the caveats of not properly synchronizing both ends of a bidirectional association.
One topic, I always wanted to investigate in great details, is about the aggressive connection release behavior employed for JTA transactions. For high-performance data access platforms, it’s worth checking if the Java EE application server can operate successfully even without aggressive connection release.
For my first post, I’d like to share the experience of running the in.relation.to blog on my Windows machine.
All the blog content is available on GitHub, and you can practically run the whole site on your local environment.
The Hibernate blog is built with awestruct from Asciidoctor files, and getting all the Ruby gems in place is definite not a walk in the park. To make matters worse, I’m running a Windows machine and all these Ruby gems are tightly coupled to Linux libraries, as I discovered after several failed attempts with the 64 bits Ruby 2.2.4 or the 32 bits Ruby 1.9.3.
Luckily, there is a dockerfile available, so building a Docker image and run it in a dedicated container can tackle the Ruby gem hell. Building the Docker image was fine, but running it was a three hours hackathon for both Emmanuel and I.
Docker images are immutable and all changes are wiped out once the container is terminated. Instead, we want the GitHub repository to be mirrored in the Docker container, so all changes are persisted even after shutting down the docker machine. This process can be done by mounting a host folder into the Docker container, which can happen upon running the Docker image. In our case, the mounted directory is the GitHub repository that’s mirrored inside the currently running Docker container.
Once the image is built, we need to run this command from within the GitHub repository folder:
docker run -t -i -p 4242:4242 -v `pwd`:/home/dev/in.relation.to hibernate/in.relation.to
This doesn’t work on Windows because Docker needs the OS paths to be prefixed with another slash.
So this command must be changed to:
docker run -t -i -p 4242:4242 -v '/'`pwd`:/home/dev/in.relation.to hibernate/in.relation.to
After running it, the mounted folder was just empty. We noticed that without the GitHub folder mounting part the Docker image could run properly, so the mounting process was the culprit.
After all sorts of hacks, Emmanuel had the idea of checking the Virtual Box Shared Folders, and, by default, only the
C:\Users directory is being shared.
No wonder it was not working all along.
All my repositories being on
D:\, we thought that adding a new shared path would fix this issue.
Well, it didn’t.
Docker must mount these Virtual Box shared folders too, but it only does so for
There’s a GitHub issue detailing this behavior, which you can watch if you are interested in this feature.
After moving the checkout GitHub repository to
/c/Users/Vlad/GitHub/in.relation.to, it all worked fine.
Welcome to the newly revamped Hibernate and friends blog.
As you can see, we made it look like hibernate.org and we took the opportunity to clean up the tags to make them more useful. But we had other reasons to migrate.
- Blog early, blog often
We have been very happy with the Asciidoctor-based writing experience of both our reference documentation and of hibernate.org. We are bringing this ease of writing to our blog and the not so secret objective is for us to blog more. So if you don’t see more content here, you can start yelling at us :)
- Write once, display anywhere
There is an added bonus to using Asciidoctor for all of our writing: we can move content easily between systems. What starts as a blog can easily become a how-to page on the site or a section in the reference documentation.
We had a few issues with the old infrastructure that were keeping us away from our IDEs a bit too often for comfort.
This blog is a statically generated site, we use Awestruct. This means that we can make is scale very easily and with very low maintenance. Nothing beats plain old HTML :)
We did migrate all the old entries and comments from the old blog: fear not, nothing is lost.
Hibernate has moved to Git (hosted on GitHub) for source control. That has been well documented. I wanted describe the approach Hibernate takes to branching, versioning and releasing as it is something that has come up a number of times, even prior to the move to Git.
For versioning, Hibernate follows the OSGi guidelines that are well described here. Here is how we view the
components that make up an OSGi version:
- major - To Hibernate, this denotes major, disruptive changes. Think back to Hibernate2 and the migration to Hibernate3 and that is the type of disruption I am talking about. The move from 3.x to 4.x will be less disruptive in that sense, but there is still a significant change.
- minor - We sometimes refer to this as a series so that you might hear Hibernate developers talk about the 3.5 series or 3.6 series. Within a series Hibernate strives for API stability. A change in this component (3.5 to 3.6) denotes some API change, though its usually an addition and therefore less disruptive than discussed above.
- micro - For Hibernate these denote bugfix releases.
- qualifier - Hibernate uses this component really only for pre-final releases (alphas, betas, etc). Once we get to Final (x.y.0.Final) we begin to increment the micro but continue to use the Final qualifier (x.y.1.Final) for release sorting (and therefore ranging) purposes.
Hibernate maintains branches for each (major.minor) series. During the move to GitHub we took the opportunity to drop off the very old branches. So currently there are
bugfix branches for 3.2, 3.3, 3.5 and 3.6 (currently the
master branch is ongoing 4.0 work). We branch off the series to make it possible to port fixes back to them. As an example... Currently the active maintenance branch is 3.6;
master is the ongoing work for 4.0. 4.0 has lots of disruptive changes as discussed above (though the same discussion holds true for series changes due to API differences). Having the 2 branches allows us to work both code-bases simultaneously. We can fix a bug and apply that change to both the 4.0 and 3.6 code-bases; yet 4.0 can evolve independently like it needs to. On
master Hibernate has moved to Gradle for its build tool and at the same time I decided to move to a more standard module directory naming scheme; unfortunately that causes some interesting challenges in trying to backport fixes which I'll discuss in a separate blog.
Hibernate performs maintenance releases from the
active maintenance branch. Currently, that means we will do maintenance releases from the 3.6 branch. We will continue to do that until 4.0 becomes Final at which point we will stop 3.6 maintenance, make 4.0 the active maintenance branch and move master to 4.1 development. This is the general outline we follow. If you look back, for example, to 3.6 development you can see that illustrated. We kept doing 3.5 maintenance releases up until the time 3.6 went Final.
The Hibernate team loosely follows a time boxing schedule for releases. Personally I don't believe in rigidity here, especially for maintenance releases. We have become very good at sticking to time boxing for Alpha, Beta and CR releases which is where I see the benefit the most. We have opted for a 2-week time box for Beta and CR releases, which has worked out really really well for us in my opinion. We have done both 2- and 4-week boxes for Alphas; we will continue to fine tune that (like I think 4.0 dev will use 4-week boxes just because there is so much change going on).
gradle -t is a handy thing to know. It will tell you all the
main tasks available in a project. Note however that it does not reach into subprojects. For example, assuming you are at the root of the Hibernate project checkout if you run gradle -t you would see nothing about tasks related to compiling, which is obviously essential :) In Gradle when you run a task against a project, that task request is passed along to any subprojects also. So I'd suggest cd'ing around a bit and doing gradle -t to get a feel for the tasks available. An alternative is to run gradle -t --all which shows all tasks for that project; just beware that that can get extremely verbose.
That being said, the here is a list of the most common tasks you will use:
- clean - Deletes the build directory.
- build - Assembles (jars) and tests this project.
- buildDependents - Assembles and tests this project and all projects that depend on it. So think of running this in hibernnate-entitymanager.. Gradle would assemble and test hibernate-entitymanager as well as hibernate-envers because envers depends on entitymanager. See below.
- classes - compiles the main classes
- testClasses - compiles the test classes.
- test - Runs the tests for this project
- jar - Generates a jar archive with all the compiled classes.
- uploadArchives - think Maven deploy
- install - I have also enabled the MavenPlugin throughout the projects, which adds this task. install installs the project jar into the local maven repository cache (usually ~/.m2/repository), which is important to inter-operate between projects using Maven to build and those using Gradle to build (otherwise you'd have to push your artifacts to Nexus to
A note about build and buildDependents. Gradle, unlike Maven, acts better in the face of inter-module dependences. In Gradle, if I cd into hibernate-entitymanager and perform a build, Gradle will automatically try to build hibernate-core for me if it needs to. For build it stops there. If you also want it to recompile things that depend on your changes, you would instead use buildDependents. So from hibernate-entitymanager again, if I this time run buildDependents it will first build hibernate-core, then hibernate-entitymanager and then hibernate-envers.
Yyou probably don't know it yet but Hibernate Core and Hibernate Validator source code is now on Git and Hibernate Search and co will likely follow very soon. There are various reasons for the move but to summarize it, life was not bad under SVN but it's really great under Git.
reference Git repository is hosted at GitHub. We are not married to GitHub but so far, we really like the infrastructure they offer. Kudos to them! In any case moving is one clone away. That tends to keep services like that on their toes.
If you want to contribute a fix or new feature, either:
- use the GitHub fork capability: clone, work on a branch, fork the repo on GitHub (fork button), push the work there and trigger a pull request (pull request button). Also see http://help.github.com/forking and http://help.github.com/pull-requests
- use the pure Git approach: clone, work on a branch, push to a public fork repo hosted somewhere, trigger a pull request git pull-request
- provide a good old patch file: clone the repo, create a patch with git format-patch or diff and attach the patch file to JIRA
Our preference is GitHub over pure Git over patches:
- GitHub lets us comment on your changes in a fine grained way
- Git generally leads to more small commits that are easier to follow
- a big fat patch of 100k is always depressing and can't be updated easliy
If you still want to do it the old way a provide a patch file, that's ok too.
While in no way comprehensive, here are a collection of useful tips when using Git.
The time will be worth it. I particularly enjoyed Pro Git. It's an awesome book and very practical. It has a free html and epub version (buying the tree version is recommended to repay the author).
Prefer the git protocol when cloning over http (so say the experts). At the very least that will be much faster. cloning the repo from GitHub took me less than 3 minutes.
#for people with read/write access git clone firstname.lastname@example.org:hibernate/hibernate-core.git #for people with read-only access git clone git://github.com/hibernate/hibernate-core.git
This will create a remote link named origin. I usually tend to rename it to reflect what it really is.
git remote rename origin core-on-github
Note that you can attach more than one remote repository to your local repository
git clone git://github.com/hibernate/hibernate-core.git git remote rename origin ref-core-github git remote add manu-core-github email@example.com:emmanuelbernard/hibernate-core.git git fetch manu-core-github
To initially get a copy of a remote branch locally, do
git checkout -b 3.6 origin/3.6
When pulling a branch, it's best to keep the same name between the origin repo and your clone. Many syntax have shortcuts in this situation (are you listening Hardy? ;) ). You can then do
git push origin master
If you happen to have renamed the branch master to say local-master locally, do
git push origin local-master:master
To delete a branch on a remote repository, you push an empty one
git push origin :branch-to-remove
Always work on a topic branch and merge your work when you are done.
git checkout master git checkout -b HHH-XXX #hack commit hack commit
Don't forget to pull from your master and rebase this topic branch before proposing request pull.
There are many advantages to this, one of them being that you can work on many different things in parallel and sync them with the reference master easily.
Likewise if you want to share a work with somebody from the Hibernate team, push to the public repo and define the pull request of your topic branch. Make sure your topic branch is above the most recent master.
Prefer small commits, they will be more readable and will very unlikely fail on merge.
Write good comments (one short line including the issue number at stake and a summary, followed by a blank line and a more detailed explanation if needed.
HHH-XXX Fix NPE on persist Fix stupid bug by Gavin that lead to a NPE when persisting objects with components
It's a debate, but here is my take on it.
- Primitive 0: DO NOT rebase a branch that you have shared publicly (unless you know people won't use it or you wish them harm).
- Primitive 1: Prefer rebase over merge assuming it does not break Primitive 0
This is particularly sensible when you trigger a pull request: rebase atop the branch you are branching of (master usually). Your work will be easier to read and integrate.
Rebase put changes from the branch you forked (say master) below the new commits you have done (say HHH-XXX) and thus keep the history linear.
git checkout HHH-XXX git rebase master
While we are at rebasing, you can rewrite your commit history to clean comments or merge some commits together (aka squashing)
git rebase -i HEAD~6 (go back 6 commits in time)
Git made backporting fun.
Say you have done some commits on master and the sha1 of the commits are ae397d... and 87ab342...
You can apply them on an older branch very easily.
git checkout 3.5 git cherry-pick ae397d git cherry-pick 87ab34
Bam, you're done. Now did I tell you to do small commits? That's also for the backporters.
Once you're fed up with typing longish command lines, use aliases. I've put a copy of my ~/.gitconfig file in case people want to copy some things including aliases (see below)
~/.gitconfig [user] name = Redacted email = firstname.lastname@example.org signingkey = id_key.pub [core] editor = open -nW -a Smultron [merge] tool = opendiff [color] ui = auto [color "branch"] current = yellow reverse local = yellow remote = green [color "diff"] meta = yellow bold frag = magenta bold old = red bold new = green bold [color "status"] added = yellow changed = green untracked = cyan [github] user = redacted token = redacted [alias] co = checkout undo = reset --hard cb = checkout -b br = branch cp = cherry-pick
If you use Mac OS X, GitX is a fantastic tool. In particular, you can very easily play with interactive staging and commit only some parts of a file in a couple of clicks. A typical use case is to separate the commit of a typo from the commit of a core feature. Some people like the built-in GitK GUI.
Command completion support via git-completion.bash is pretty good if you are command shell type person. The script is available in the Git project sources and in other places (including Fedora). Pro Git has some more information on it.
You can also read this blog entry that was some more info for people moving from SVN to Git.
This entry is too long already, feel free to add your tips in the comments.