Hibernate annotation to the rescue when mapping files cannot be located

Forget hibernate mapping files, seriously unless you really need to. Use annotations instead. Then you need not worry about running into class path issues.

This is the story:

I wanted to create a simple RESTFul service which exposes simple CRUD functionality on data within a PostgreSQL database. In a previous post,
I briefly covered using Hibernate to connect to a PostgreSQL database to retrieve entities within the context of a RESTful webservice. This all worked flawlessly since the deployment target was IntelliJ’s embedded http server. When it came time to deploy the resulting .war to a local Tomcat instance, all hell broke loose.

I used the the Jersey archetype for Maven which gave provided a directory structure like this:

|- src
   |- main
      |- java
         |-my-app
            - User.java
            - HibernateUtils.java
            .......
      |- resources
          - hibnernate.cfg.xml
          - user.hbm.xml

As stated earlier, everything worked as expected when deployed to IntellJ’s local http server. However, when .war file was deployed to a local Tomcat instance on the same box, hibernate was not able to find a mapping for the user entity. The error was

User is not mapped [from User where id > :id]

for a class defined as follows:

public class User {
    private int id;
    private String _firstName;
    private String _lastName;

    public String getFirstName(){
        return _firstName;
    }
    public void setFirstName(String name){
        _firstName = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getLastName() {
        return _lastName;
    }

    public void setLastName(String _lastName) {
        this._lastName = _lastName;
    }

    @Override public String toString(){
        return String.format("%s %s", _firstName, _lastName);
    }
}

The hibernate files were all in place and mappings were all correct. After spending a couple of days and not seemingly getting anywhere, questioning my sanity, I decided on another approach: annotations. After all, this is the common pattern when using the Entity Framework in .NET.

The User class was modified as follows:

import javax.persistence.*;

/**
 * Created by Klaus on 31/08/2015.
 */
@Entity
@Table( name = "users" )
public class User {

    @Id
    @GeneratedValue
    private int id;

    @Column (name = "firstname")
    private String _firstName;

    @Column (name = "lastname")
    private String _lastName;

    /* rest of code ignored for brevity */
}

HibernateUtils was also modified:

public class HibernateUtils {
    private static SessionFactory sessionFactory;

    public static SessionFactory getSessionFactory() {

        if (sessionFactory == null) {
            // loads configuration and mappings
            Configuration configuration =
                    new Configuration()
                            .addAnnotatedClass(User.class)
                            .configure();

            ServiceRegistry serviceRegistry
                    = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties()).build();

            // builds a session factory from the service registry
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        }

        return sessionFactory;
    }

Repacking, deploying to IntelliJ’s local http server ensured functionality was not broken. Next, deploying to a local instance of Tomcat on the local machine, also proved successful. This left me pondering for a while…. but there are things to get done…

What happened here remains a mystery which begs for an explanation. Could a unit test have saved me endless hours deploying to Tomcat?

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s