Java Persistence with Hibernate

Christian Bauer, Gavin King

Mentioned 20

A guide to using Hibernate and Java Persistence covers such topics as ORM, application architecture, and developer tools.

More on Amazon.com

Mentioned in questions and answers.

Let's say I have a table with millions of rows. Using JPA, what's the proper way to iterate over a query against that table, such that I don't have all an in-memory List with millions of objects?

For example, I suspect that the following will blow up if the table is large:

List<Model> models = entityManager().createQuery("from Model m", Model.class).getResultList();

for (Model model : models)
{
     System.out.println(model.getId());
}

Is pagination (looping and manually updating setFirstResult()/setMaxResult()) really the best solution?

Edit: the primary use-case I'm targeting is a kind of batch job. It's fine if it takes a long time to run. There is no web client involved; I just need to "do something" for each row, one (or some small N) at a time. I'm just trying to avoid having them all in memory at the same time.

Page 537 of Java Persistence with Hibernate gives a solution using ScrollableResults, but alas it's only for Hibernate.

So it seems that using setFirstResult/setMaxResults and manual iteration really is necessary. Here's my solution using JPA:

private List<Model> getAllModelsIterable(int offset, int max)
{
    return entityManager.createQuery("from Model m", Model.class).setFirstResult(offset).setMaxResults(max).getResultList();
}

then, use it like this:

private void iterateAll()
{
    int offset = 0;

    List<Model> models;
    while ((models = Model.getAllModelsIterable(offset, 100)).size() > 0)
    {
        entityManager.getTransaction().begin();
        for (Model model : models)
        {
            log.info("do something with model: " + model.getId());
        }

        entityManager.flush();
        entityManager.clear();
        em.getTransaction().commit();
        offset += models.size();
    }
}

Someone suggested I use an ORM for a project I'm designing but I'm having trouble finding information on what it is or how it works. Can anyone give me a brief explanation or a link as to where I can learn more about it?

The first chapter of the Hibernate book Java Persistence with Hibernate (3rd ed.) has an excellent overview of general ORM concepts and discusses motivation and design of ORMs. Highly recommended, even if you don't work with Java.

I have a one-to-one relationship but hibernatetool complains when generating the schema. Here's an example that shows the problem:

@Entity
public class Person {
    @Id
    public int id;

    @OneToOne
    public OtherInfo otherInfo;

    rest of attributes ...
}

Person has a one-to-one relationship with OtherInfo:

@Entity
public class OtherInfo {
    @Id
    @OneToOne(mappedBy="otherInfo")
    public Person person;

    rest of attributes ...
}

Person is owning side of OtherInfo. OtherInfo is the owned side so person uses mappedBy to specify the attribute name "otherInfo" in Person.

I get the following error when using hibernatetool to generate the database schema:

org.hibernate.MappingException: Could not determine type for: Person, at table: OtherInfo, for columns: [org.hibernate.mapping.Column(person)]
        at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:292)
        at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:175)
        at org.hibernate.cfg.Configuration.iterateGenerators(Configuration.java:743)
        at org.hibernate.cfg.Configuration.generateDropSchemaScript(Configuration.java:854)
        at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:128)
        ...

Any idea why? Am I a doing something wrong or is this a Hibernate bug?

JPA doesn't allow the @Id annotation on a OneToOne or ManyToOne mapping. What you are trying to do is one-to-one entity association with shared primary key. The simplest case is unidirectional one-to-one with shared key:

@Entity
public class Person {
    @Id
    private int id;

    @OneToOne
    @PrimaryKeyJoinColumn
    private OtherInfo otherInfo;

    rest of attributes ...
}

The main problem with this is that JPA provides no support for shared primary key generation in OtherInfo entity. The classic book Java Persistence with Hibernate by Bauer and King gives the following solution to the problem using Hibernate extension:

@Entity
public class OtherInfo {
    @Id @GeneratedValue(generator = "customForeignGenerator")
    @org.hibernate.annotations.GenericGenerator(
        name = "customForeignGenerator",
        strategy = "foreign",
        parameters = @Parameter(name = "property", value = "person")
    )
    private Long id;

    @OneToOne(mappedBy="otherInfo")
    @PrimaryKeyJoinColumn
    public Person person;

    rest of attributes ...
}

Also, see here.

I'm a PHP developer who knows a little bit of Ruby. I want to learn Ruby on Rails, but most of the resources I've come across treat RoR functionality as "magic" -- i.e., it has a certain internal consistency, but don't bother asking how it works in terms of Ruby, MySQL, etc.

Anyway, I want a deep understanding of how RoR works, the design decisions that went into building it, etc. In particular I'm interested in ActiveRecord, but really I'm looking for the whole package.

Any books / sites / advice welcome.

If you really want to know how it works, you can just look at the source code. The online API docs let you see the source code of every method right in the documentation page.

ActiveRecord in Rails is based on Martin Fowler's Active Record pattern. It's basically an ORM (object-relational mapper). It's not even really that sophisticated as far as ORMs go. Java Persistence with Hibernate has a good overview of common ORM concepts.

I'm trying to get started with hibernate, but I can't find any tutorials I understand. I'm trying to create a simple app to get started, but I've really no idea where to get started.

I'm pretty advanced with java, although only used eclipse really. So.. where do I configure what DB it uses, and alike?

[edit]
I'm familiar with the concepts of ORM, and what Hibernate is. What I don't know or understand, is where to begin my application. I intend to use annotations, but, after annotating my POJOs, what do I do? Where do I specify database server, user, etc? What else do I need to do?

My experiences and background were similar, and I also had a hard time finding a tutorial that addressed my development preferences (which seem similar to yours):

  • Prefer JPA annotations over XML, only adding Hibernate annotations when the JPA counterparts do not suffice
  • Use Hibernate's SessionFactory / Session to access persistent data rather than JPA EntityManager
  • Use immutable classes wherever possible

I read most of Java Persistence with Hibernate, and it took a long time to separate this use case from all the other options that it presents (XML configuration in Hibernate/JPA format, xdoclet "annotations", etc...).

It would have made so much more sense to me if the available documentation would take a stand and actively push me in this direction instead of giving me a bunch of options and wondering where to go. Lacking that, I learned the following lessons by converting the standard Hibernate Tutorial over to annotations.

Configuration

  • Keep hibernate.cfg.xml to the bare minimum (see below).
  • Define database column / table names explicitly with the JPA annotations so you get exactly the schema you want. You can double-check it by using SchemaExport.create(true, false). Note that you may not get the exact schema you expect if Hibernate tries to update the schema on an existing database (for example, you can't add a NOT NULL constraint to a column that already contains null values).
  • Create the SessionFactory's Configuration using AnnotationConfiguration.addAnnotatedClass().addAnnotatedClass()...

Here's my copy of hibernate.cfg.xml. It only sets properties, and explicitly avoids any mapping configuration.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Information about the database to be used -->
        <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
        <property name="connection.username">sa</property>
        <property name="connection.password"></property>
        <property name="connection.pool_size">1</property>
        <property name="dialect">org.hibernate.dialect.HSQLDialect</property>

        <!-- Misc. Hibernate configuration -->
        <property name="hbm2ddl.auto">update</property>
        <property name="current_session_context_class">thread</property>
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <property name="show_sql">false</property>
    </session-factory>
</hibernate-configuration>

Scope

  • Begin/commit/rollback transactions outside each Manager / DAO class. I have no idea why the tutorial's EventManager starts/commits its own transactions, as the book identifies this as being an anti-pattern. For the servlet in the tutorial, this can be done by making a Filter that starts the transaction, invokes the rest of the FilterChain, and then commits/rolls back the transaction.
  • Similarly, make the SessionFactory outside and pass it in to each Manager / DAO class, which then calls SessionFactory.getCurrentSession() any time it needs to access data. When it comes time to unit test your DAO classes, make your own SessionFactory that connects to an in-memory database (such as "jdbc:hsqldb:mem:test") and pass it into the DAO being tested.

For example, some snippets from my version of EventManager:

public final class EventManager {

private final SessionFactory sessionFactory;

/** Default constructor for use with JSPs */
public EventManager() {

    this.sessionFactory = HibernateUtil.getSessionFactory();
}

/** @param Nonnull access to sessions with the data store */
public EventManager(SessionFactory sessionFactory) {

    this.sessionFactory = sessionFactory;
}

    /** @return Nonnull events; empty if none exist */
public List<Event> getEvents() {

    final Session db = this.sessionFactory.getCurrentSession();
    return db.createCriteria(Event.class).list();
}

/**
 * Creates and stores an Event for which no people are yet registered.
 * @param title Nonnull; see {@link Event}
 * @param date Nonnull; see {@link Event}
 * @return Nonnull event that was created
 */
public Event createEvent(String title, Date date) {

    final Event event = new Event(title, date, new HashSet<Person> ());
    this.sessionFactory.getCurrentSession().save(event);
    return event;
}

/**
 * Registers the specified person for the specified event.
 * @param personId ID of an existing person
 * @param eventId ID of an existing event
 */
public void register(long personId, long eventId) {

    final Session db = this.sessionFactory.getCurrentSession();
    final Person person = (Person) db.load(Person.class, personId);
    final Event event = (Event) db.load(Event.class, eventId);
    person.addEvent(event);
    event.register(person);
}

...other query / update methods...
}

Data classes

  • Fields are private
  • Getter methods return defensive copies since Hibernate can access the fields directly
  • Don't add setter methods unless you really have to.
  • When it is necessary to update some field in the class, do it in a way that preserves encapsulation. It's much safer to call something like event.addPerson(person) instead of event.getPeople().add(person)

For example, I find this implementation of Event much simpler to understand as long as you remember that Hibernate accesses fields directly when it needs to.

@Entity(name="EVENT")
public final class Event {

    private @Id @GeneratedValue @Column(name="EVENT_ID") Long id; //Nullable

    /* Business key properties (assumed to always be present) */
    private @Column(name="TITLE", nullable=false) String title;

    @Column(name="DATE", nullable=false) 
    @Temporal(TemporalType.TIMESTAMP)
    private Date date;

    /* Relationships to other objects */
    @ManyToMany
    @JoinTable(
        name = "EVENT_PERSON",
        joinColumns = {@JoinColumn(name="EVENT_ID_FK", nullable=false)},
        inverseJoinColumns = {@JoinColumn(name="PERSON_ID_FK", nullable=false)})
    private Set<Person> registrants; //Nonnull

    public Event() { /* Required for framework use */ }

    /**
     * @param title Non-empty name of the event
     * @param date Nonnull date at which the event takes place
     * @param participants Nonnull people participating in this event
     */
    public Event(String title, Date date, Set<Person> participants) {

        this.title = title;
        this.date = new Date(date.getTime());
        this.registrants = new HashSet<Person> (participants);
    }

    /* Query methods */

    /** @return Nullable ID used for persistence */
    public Long getId() {

        return this.id;
    }

    public String getTitle() {

        return this.title;
    }

    public Date getDate() {

        return new Date(this.date.getTime());
    }

    /** @return Nonnull people registered for this event, if any. */
    public Set<Person> getRegistrants() {

        return new HashSet<Person> (this.registrants);
    }

    /* Update methods */

    public void register(Person person) {

        this.registrants.add(person);
    }
}

Hope that helps!

I was looking at ayende blog http://ayende.com/blog/3946/nhibernate-mapping-concurrency about NHibernate concurrency and i still not very clear when to use . It seems like it is a solution to solve StaleObjectException.

Can anyone explain to me in what scenario you will use a and why ?

Thanks.

NHibernate Version is used when you want to implement Optimistic concurrency control. Without enabling Optimistic concurrency control and locking your application will use "Last commit wins" strategy. Your users may experience lost updates if two transactions are modifying the same object at roughly the same time. The more appropriate strategy is called "First commit wins". In this scenario second transaction will fail with an error that would say something like: Somebody already committed modifications to the data you’re about to commit. You’ve been working with stale data. Please restart the conversation with fresh data.

From Java Persistence with Hibernate:

Hibernate provides automatic versioning. Each entity instance has a version, which can be a number or a timestamp. Hibernate increments an object’s version when it’s modified, compares versions automatically, and throws an exception if a conflict is detected. Consequently, you add this version property to all your persistent entity classes to enable optimistic locking. ... The version number is just a counter value—it doesn’t have any useful semantic value. The additional column on the entity table is used by your Hibernate application. Keep in mind that all other applications that access the same database can (and probably should) also implement optimistic versioning and utilize the same version column.

I got a problem with a many to many association in my persistence layer. My scenario is the following:

A user can has several roles and a role can have several user attached to it. During the tests I encountered a strange behavior. I created role object and several user objects. The role was set to each of the users. After this the users were saved using a DAO. Then one of the user gets loaded to check whether he got the role that was passed to him before saving the user object. Calling getRoles() on the user shows that the role was set correctly.

To check whether the inverse direction also works the role object gets loaded from the database using a role DAO. But calling getUsers() on the role object just returns an empty set, although it should contain all the users with this role.

I double checked the database table but everything seems all right. User, role and user_role table were all filled correctly.

So why doesn't the role object contain any user?

I'm using Hibernate and Spring with the following classes.

User class

@Entity
@Table
public class User extends BusinessObject {

    ... 

    // Option 1
    @ManyToMany(fetch = FetchType.LAZY,
                cascade = CascadeType.ALL,
                targetEntity=Role.class)
    @JoinTable(name= "user_role",
               joinColumns = {@JoinColumn(name="user_id")},
               inverseJoinColumns = {@JoinColumn(name="role_id")})  

    // Option 2
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name= "user_role", 
                   joinColumns = {@JoinColumn(name="user_id")},
           inverseJoinColumns = {@JoinColumn(name="role_id")})
    private Set<Role> roles = new HashSet<Role>();      

    ... 
}

Role class

@Entity
@Table
public class Role extends BusinessObject {
    ...

    // Option 1
    @ManyToMany(fetch = FetchType.LAZY, 
                cascade = CascadeType.ALL,
                mappedBy= "roles",
                targetEntity = User.class)

    // Option 2
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name= "user_role", 
                   joinColumns = {@JoinColumn(name="role_id")},
                   inverseJoinColumns = {@JoinColumn(name="user_id")})
    private Set<User> users = new HashSet<User>();          

    ... 
}

To test I'm using the following code in a JUnit test class.

@Test
public void test(){     
    Transaction trans = sessionFactory.getCurrentSession().beginTransaction();

    Role userAdminRole = new Role();
    userAdminRole.setName(RoleName.USER_ADMIN);
    Role userRole = new Role();
    userRole.setName(RoleName.USER);

    User user1 = new User();
    user1.setEmail("user1@user.de");        
    user1.getRoles().add(userAdminRole);
    user1.getRoles().add(userRole);
    userDao.save(user1);

    User user2 = new User();
    user2.setEmail("user2@user.de");
    user2.getRoles().add(role);
    userDao.save(user2);

    User user3 = new User();
    user3.setEmail("user3@user.de");
    user3.getRoles().add(role);
    userDao.save(user3);            

    trans.commit();     

    User loadedUser = userDao.load(user1.getId());

            // Tests passes
    Assert.assertNotNull(loadedUser);
    Assert.assertEquals(user1, loadedUser);

    Set<Role> roles = loadedUser.getRoles();        

            // Tests passes
    Assert.assertEquals(2, roles.size());

    Role loadedUserAdminRole = roleDao.findByName(RoleName.USER_ADMIN);
    Set<User> users = loadedUserAdminRole.getUsers();

    // Test fails: Count is 0 instead of 3 !!!!!!!
    Assert.assertEquals(3, users.size());
}  

UPDATE

Sorry I forgot to mention one thing. When I tested the code I of course didn't mark the many to many association twice in each class file. Instead I used either option 1 or option 2 in each class file.

When dealing with a bidirectional many-to-many association you have to maintain both ends of the association. In your case, you have to add the user to the role as well. Adding the role to the user isn't sufficient to establish a bidirectional association as you can read in book Java Persistance with Hibernate:

As always, a bidirectional association (no matter of what multiplicity) requires that you set both ends of the association.

Hi I am working on hibernate and need some information about the stateless session. tried to search on google but didnt get that much information. so please need any link or pdf's about stateless session on how, why and when to use it. what are the pros and cons of using it. thanks

The book Java Persistence with Hibernate has a short, but sufficient section about stateless session in Hibernate. If you do not want to buy a copy of that book just for that information, I found the whole book on slideshare.com; Section 12.2.3, page 539 (page 574 on slideshare.com).

We use single table inheritance for every table in our application. This allows different instances of the same application stack to work with the same DAOs while their entities might differ slightly potentially containing information unique to that instance. An abstract class defines the basic table structure and an extension defines additional columns, if needed by that instance:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "client")
public abstract class Client extends AbstractPersistable<Long> {
    // ...
}

application A:

@Entity
public class ClientSimple extends Client {
    private String name;
    // getter, setter
}

application B:

@Entity
public class ClientAdvanced extends Client {
    private String description;
    // getter, setter
}

Now a DAO can work with Client objects for application A and B but application B can define additional information for its client object that may be read by a manager method unique to application B:

application A:

Client client = new ClientSimple();
clientDao.save(client);

application B:

Client client = new ClientAdvanced();
clientDao.save(client);

Unfortunately this means there is a DTYPE column in every table (or any other name that I might choose). Is there any way to get rid of this? We don't need it and it's using up DB space...

Thanks!


EDIT

Important to note: @MappedSuperclass won't work. We're using QueryDSL as our HQL abstraction layer. This requires automatically generated Query Type classes for type save querying. These however will only be generated correctly if the abstract class is annotated with @Entity.

This is neccessairy because we want to query against the abstract class Client while in truth querying ClientSimple in application A and ClientAdvanced in application B:

So in any application this will work:

query.where(QClient.client.name.equals("something");

and in application B this will work:

query.where(QClientSimple.client.description.equals("something else");

EDIT2 - boil down

It seems to boil down to this: Can I configure hibernate at deploy time to set the discriminator type for an inhertited entity to a fixed value. So going with my example a Client will always be ClientSimple in one application and ClientAdvanced in the other so that I don't have to store that information in the database?

Like I said: Each application will be an instance of the base application stack. Each application might define additional columns for their local database but ALL objects will be of the same type for that instance so we guarantee that the discriminator is always the same making it redundant in the database and a use case for hibernate configuration.

I know, this is a very old question, but I encountered this problem recently and this might prove useful to someone.

This can be done using Hibernate's @DiscriminatorFormula annotation. The following description is based on the book Java Persistence with Hibernate, section 5.1.3; the relevant part begins at page the last paragraph on page 202.

With @DiscriminatorFormula you can provide an SQL statement that determines the value of the discriminator while fetching the relevant rows from the database. In your case, it would have to be a simple string that evaluates to some arbitrarily selected value. For this to work, you need to decide upon a name that would be used for your Client entity. Suppose that you select 'GenericClient' as the name of the entity. This is the name that should appear within @Entity annotation as the value of the name attribute. So, the complete example, in your case would look like the following.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "client")
@DiscriminatorFormula("'GenericClient'")  // *1*
public abstract class Client extends AbstractPersistable<Long> {
    // ...
}

// Application A
@Entity
@DiscriminatorValue("GenericClient")  // *2*
public class SimpleClient extends Client {
    // ...
}


// Application B
@Entity
@DiscriminatorValue("GenericClient")  // *3*
public class AdvancedClient extends Client {
    // ...
}

The line that is denoted by '1' is a part of the SQL snippet that will always return 'GenericClient' as its value. The subclasses of the Client should always be annotated with the @DiscriminatorValue("GenericClient"). What this means is that when Hibernate fetches the rows from the DB, the type of the object to be constructed would always be the specific subclass of Client.

If the package where the subclasses of Client reside, and the name of the subclasses are fixed:

In that case, the @DiscriminatorValue("GenericClient") on the sub-classes wouldn't be required, all you would need to do is:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "client")
@DiscriminatorFormula("'com.example.fixed.path.FixedSubClassName'")
public abstract class Client extends AbstractPersistable<Long> {
    // ...
}

The subclasses wouldn't need any annotations. The discriminator-value defaults to the entity-name, which itself defaults to the fully-qualified class-name.

Note: The SQL statement inside @DiscriminatorFormula() can be any valid SQL statement for your targeted DB server.

So i am stuck, i am creating a gwt web application, i will be using a tree(gwt Tree and TreeItems) structure to show a list of folders(class Folder) and files(class FileLocation), the folder and filelocation class will all implement a Hierarchy interface basing the classes on the composite pattern. but i am using hibernate to store my data , and i am using annotations for the mapping of the data to the database. my trouble is i do not know how to annotate my interface.

have any of you guys used the composite pattern while persisting the data with hibernate

public interface Hierarchy(){
// a few abstract methods that will be implemented by the sub classes
 }


@Entity
@Table()
public class Folder implements Serializable, Hierarchy {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "folder_id", updatable = false, nullable = false)
private int id;
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinTable(name = "FOLDER_FILELOCATION", joinColumns = { 
        @JoinColumn(name = "folder_id") }, inverseJoinColumns = { 
        @JoinColumn(name = "file_information_id") })
private List<Hierarchy> children = new ArrayList<Hierarchy>() ;
@Column(name = "folder_name")
private String folderName;
@Column(name = "tree_item")
private TreeItem item;
@Column (name = "parent")
private Hierarchy parent;



@Entity
@Table(name = "FILE_INFORMATION_TABLE")
public class FileInformation implements Serializable, Hierarchy {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "file_information_id", updatable = false, nullable = false)
private int fiId;
@Column (name = "location")
private String location;
@Column(name = "tree_item")
private TreeItem item;
@Column (name = "parent")
    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    @JoinTable(name="FOLDER_FILELOCATION",
    joinColumns = @JoinColumn(name="filelocation_id"),
    inverseJoinColumns = @JoinColumn(name="folder_ID"))  
private Hierarchy parent;

After a look through the hibernate documentation and This Book i was able to find a solution to my problem. i cannot use an interface for the moment with JPA annotations. so i used an abstract class with mappings that supported inheritance. in this example i use a single table to store all the values. but i wil look in to seperating them.

@Entity
@Table(name ="HIERARCHY")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(
    name = "HIERARCHY_TYPE", discriminatorType = DiscriminatorType.STRING)      
public abstract class  Hierarchy implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "hierarchy_id", updatable = false, nullable = false)
private int hId;



@Entity
@DiscriminatorValue("F")
public class Folder extends Hierarchy  {

@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinTable(name = "FOLDER_JOIN_FILELOCATION", joinColumns = { 
        @JoinColumn(name = "folder_id") }, inverseJoinColumns = { 
        @JoinColumn(name = "file_information_id") })
private List<Hierarchy> children = new ArrayList<Hierarchy>() ;
@Column(name = "folder_name")
private String folderName;
//@Column(name = "tree_item")
//private TreeItem item;
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
   @JoinTable(name="FOLDER_JOIN_FOLDER",
        joinColumns = @JoinColumn(name="parent_folder_id"),
        inverseJoinColumns = @JoinColumn(name="folder_ID")
    ) 
private Hierarchy parent;




@Entity
@DiscriminatorValue("FI")
public class FileInformation extends Hierarchy  {


@Column (name = "location")
private String location;
//@Column(name = "tree_item")
//private TreeItem item;
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
   @JoinTable(name="FILEINFORMATION_JOIN_FOLDER",
        joinColumns = @JoinColumn(name="filelocation_id"),
        inverseJoinColumns = @JoinColumn(name="folder_ID")
    )  
private Hierarchy parent;

I have a simple question regarding Entity declaration in JPA. I have an entity with 2 foreign keys, which are not null and form an uniqueConstraint. First I was thinking about a composite key, composed of the two foreign keys, but I heard that this is a legacy design, and not the recommended way of designing new tables.

So I am interested if Hibernate/JPA can automatically generate id, based on the two foreign keys. Let's say I have the following Entity:

@Entity
public class Foo {
  @ManyToOne
  private Bar bar;
  private int i;
}

(I omitted not null and uniqueConstraint tags to make the code more readable)

I know I can simply add an id field, with GeneratedValue, and let my DB generate the key (in my example MySQL with auto_increment), but this seems inefficient to me as it involves querying the database, and asking it to generate the unique id value.

Is there a way of generating an id, which is not composite (i.e. of type int or long), based on the id of the "Bar" class, and value of the integer "i", since it those two values already form a unique constraint?

You may want to check out Chapter7 of "Java Persistence with Hibernate".

You can model the composite key as an Embeddable:

import javax.persistence.*;
import java.io.Serializable;

@Entity
public class Foo {

    @Embeddable
    public static class Id implements Serializable {
        @Column(name = "bar_id_col")
        private Long barId;

        @Column(name = "i_col")
        private int i;

        public Id() {
        }

        public Id(Long barId, int i) {
            this.barId = barId;
            this.i = i;
        }

        @Override
        public boolean equals(final Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof Id)) {
                return false;
            }

            final Id id = (Id) o;

            if (i != id.i) {
                return false;
            }
            if (barId != null ? !barId.equals(id.barId) : id.barId != null) {
                return false;
            }

            return true;
        }

        @Override
        public int hashCode() {
            int result = barId != null ? barId.hashCode() : 0;
            result = 31 * result + i;
            return result;
        }
    }

    @EmbeddedId
    private Id id = new Id();

    @ManyToOne
    @JoinColumn(name = "bar_id_col", insertable = false, updatable = false)
    private Bar bar;

    private int i;

    public Foo() {
    }

    public Foo(Bar bar, int i) {
        // set fields
        this.Bar = bar;
        this.i=i;
        // set identifier values
        this.id.barId = bar.getId();
        this.id.i = i;
    }

}

Here I assume Bar looks like:

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Bar {

    @Id
    Long id;

    public Long getId() {
        return id;
    }

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

Notice that this maps the bar_id_col twice. This is the reason for insertable = false, updatable = false in the second reference.

It's tricky, but if you really want to do it like this, it's possible.

Good luck, J.

Basically I want to learn this technology. I already know Java SE. My question is, what is a good start to learn Spring and Hibernate? Is the book Head First JSP and Servlets good or what?

There are many topics under the Spring framework. The ones that I use most are - IOC, AOP, Transaction Management, and Spring JDBC. In order to grasp these concepts I used the spring website extensively and also read the Spring Recipes book. I coded the examples that were on the book and tried to convert an existing app in using the spring framework (like IOC and JDBC). The spring forum is very useful. An of course folks here at Stack Overflow are always willing to help.

I could recommend you Pro Spring 2.5 by Rob Harrop and Jan Machacek. It's quite easy to read and there are quite a lot of simple, but precise examples. And, of course, Spring has very good reference.

And if you want to know more about Hibernate, you should definetely take a look at Java Persistence with Hibernate. One of the author is Gavin King, creator of Hibernate, so while reading this book you're getting first hand knowledge.

Does nhibernate use a generic hash and equality generator (derived from primary key definitions) for its identity map? That's one way of doing it I guess. I was wondering how nhibernate went about achieving this.

Why bother? I was asked to use a database that could use nhibernate, but it is not supported by the community right now (it was in the past). Just want to hack my way forward. I may come back to this later and write that nhibernate layer / plugin, but that's overkill and a little bit beyond my resources at this time.

After posting the question I found these refences below [1]. It'd be nice to find a book or a web post that went through the different edge cases.

reference [1]:

Good identity map implementations?

Take a look at

  • StatefulPersistenceContext
  • IdentityMap
  • SequencedHashMap

in Nhibernate sources for a good identity map implementation.

I was asked to use a database that could use nhibernate, but it is not supported by the community right now (it was in the past).

If I understood you correctly you wanted to write your own ORM-like layer because NHibernate does not support the database you want. It can be a daunting task. You might want to look at extending NHibernate by providing your own Driver and Dialect.

It'd be nice to find a book or a web post that went through the different edge cases.

There is already a a very good description in Java Persistence with Hibernate: 9.2 Object identity and equality. And in online NHibernate docs: 4.3. Implementing Equals() and GetHashCode().

For a project I am working on, I need to persist a number of POJOs to a database. The POJOs class definitions are sometimes highly nested, but they should flatten okay, as the nesting is tree-like and contains no cycles (and the base elements are eventually primitives/Strings). It is preferred that the solution used create one table per data type and that the tables will have one field per primitive member in the POJO. Subclassing and similar problems are not issues for this particular project.

Does anybody know of any existing solutions that can:

  1. Automatically generate a CREATE TABLE definition from the class definition
  2. Automatically generate a query to persist an object to the database, given an instance of the object
  3. Automatically generate a query to retrieve an object from the database and return it as a POJO, given a key.

Solutions that can do this with minimum modifications/annotions to the class files and minimum external configuration are preferred.


Example:

Java classes

//Class to be persisted
class TypeA {
  String guid;
  long timestamp;
  TypeB data1;
  TypeC data2;
}

class TypeB {
  int id;
  int someData;
}

class TypeC {
  int id;
  int otherData;
}

Could map to

CREATE TABLE TypeA (
  guid CHAR(255),
  timestamp BIGINT,
  data1_id INT,
  data1_someData INT,
  data2_id INt,
  data2_otherData INT
);

Or something similar.

Hibernate can help you solve all the three problems you listed.

(1) You need to annotate your entity classes so Hibernate is able to map between classes/objects to tables/rows. Hibernate uses a convention over configuration approach so it is possible to use just a few annotations and have a complete o/r mapping ready for use. You could use the hibernate.hbm2ddl.auto configuration option to instruct Hibernate to automatically validate/export and schema DDL when the session factory is first created.

(2) / (3) Hibernate has enough information about classes, database schema and mappings to allow it generate SQL statements for simple CRUD operations with minimal effort. You can fine tune how Hibernate loads and persists a tree of objects. Association mapping annotations have the fetch and cascade options that let you specify how associated objects are fetched (lazy / eager) and how operations are propagated through the object tree. Please refer to the Hibernate documentations for the details about these options.

If you are new to Hibernate, I recommend the good Hibernate documentation as reference and the book Java Persistence with Hibernate for the deeper understanding about the framework (it has very good sections about fetching and cascading).

In a typical scenario, Hibernate requires just a bit of configuration (one hibernate.cfg.xml file). You can define the mappings using XML files (no good) or annotations (the "default" option for new projects).

I have a problem with my mappings Employee and Project: For example in Employee mapping I have "bag" to map other tables. The problem is when I open the Employee window, this take a lot of time(10 sec) opening the Window, how can I make the mapping better and also faster? Maybe in the lazy or in the fetch?.

This is the mapping for Employee:

  <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="AdminProject"
                   namespace="AdminProject.Business.Entity">
  <class name="Employee">

    <id name="EmployeeId" type="int">     
    </id>

    <property name="OperatorNum" 
        generated="always" 
        update="false" 
        insert="false" 
        type="int"/>
    <property name="Password" type="string"/>
    <property name="Name" type="string"/>
    <property name="LastName" type="string"/>
    <property name="DateBegin" type="DateTime"/>
    <property name="DateEnd" type="DateTime"/>
    <property name="Telephone" type="string"/>
    <property name="Address" type="string"/>

    <many-to-one 
        name="EmployeeState" 
        column="EmployeeStateId" 
        class="EmployeeState" 
        fetch="join"/>

    <bag name="EmployeebyProject" lazy="false">
      <key column="EmployeeId"/>
      <one-to-many class="EmployeebyProject"/>
    </bag>

    <bag name="EmployeeComments" lazy="false">
      <key column="EmployeeId"/>
      <one-to-many class="EmployeeComments"/>
    </bag>

  </class>

</hibernate-mapping>

Thanks..

You should use SQL Server Profiler to figure out what is being loaded from your database. Alternatively you can set NHibernate to log SQL. This way it will be easier for you to see what causes the delay. Very likely that it is caused by eagerly loading collections (your mapping has lazy="false"). If this is the case you can simply set it to true (default).

<bag name="EmployeebyProject" lazy="true">
  <key column="EmployeeId"/>
  <one-to-many class="EmployeebyProject"/>
</bag>

<bag name="EmployeeComments" lazy="true">
  <key column="EmployeeId"/>
  <one-to-many class="EmployeeComments"/>
</bag>

Your many-to-one association is also loaded eagerly (fetch="join").

One of the popular approaches is to have all associations lazy (Lazy Default Fetch Plan). And then use eager loading in places where you are sure you will need association loaded. This however depends on your session management because lazy loading will not work if session is no longer available. There is a very good description of fetch plans and strategies in this book.

I am using Spring 3.2 and hibernate-core 4.1.4 and hibernate-jpa-2.0.1. The application resource file has all the correct objects.

I have a child object RoleEntity, and it has two parents: User and Award, so the userId and the awardId are foreign-keys that already exist, and MUST exist for the role entity to be created.

public class RoleEntity implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "role_id")
    private long roleId;

    @Column(name = "role_description")
    private String roleDescription;

    @Column(name = "role_name")
    private String roleName;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private UserEntity user;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "award_id")
    private AwardEntity award;

     ... getters/setters
     ... hash/equals/toString
}

My DAO insert looks very simple:

@Override
public RoleEntity saveRoleEntity(RoleEntity role)
{
     logger.debug("saveRoleEntity: role=" + role);
     return role;
}

I have unit tested this code, and I can confirm that when I select an existing roleId, I can fully get back the loaded object, with User and Award fully populated.

However, when I insert new role, I do the following:

  1. set roleId to 0, and the role description ...
  2. create a userEntity and set the id only, this id already exists and is not new
  3. create a awardEntity and set the id only, this id already exists and is not new

I can successfully do a save and this is great!!!! Works for me. And in the new object return, I can clearly see the new roleId is returned to me!!! All the other fields to RoleEntity, like the description, that is there.

But, what I ALSO want is for the User and Award fields of the RoleEntity to be fully populated as if I had done a select after the insert. Is this even possible?

I would prefer to not do a select to the user and award tables to get those objects and then assign them to this object, but if I have to do that, then that's fine.

If I need to provide any more information, please let me know. Thanks for any help in advance.

Two things here. First of all you shouldn't create new entities with known IDs just to use this ID. This approach is an accident waiting to happen: an entity with this ID already exists and you will run into a ConstraintViolationException or NonUniqueObjectException because of this duplicate key.

With Hibernate you can use proxies if you want to use an entity with a known ID but you do not want to select the full entity from the database.

UserEntity user = session.load(UserEntity.class, userId);
AwardEntity award = session.load(AwardEntity.class, awardId);

This will not hit the database to select the entities but a proxy (which wraps the known id) will be returned. Within the same session you can than use the proxy like the full entity and create the new RoleEntity

RoleEntity role = new RoleEntity();
role.setUser(user);
role.setAward(award);
session.save(role);

The second thing is: how should Hibernate know the non-id properties of your entities without hitting the database!? The only way Hibernate could do this is using the Second Level Cache (L2C), but from your question I assume that there is no L2C in place.

Even though your @ManyToOne associations are eager-fetched Hibernate must hit the database to populate the according entities. So you may use the approach from @Bogdan's answer and re-load the role and associated user and award entities after the insert

session.save(role);
session.refresh(role);

but this will have no performance benefit over selecting the according entities first in order to assign them to the new role

UserEntity user = session.get(UserEntity.class, userId);
AwardEntity award = session.get(AwardEntity.class, awardId);    

This will hit the database immediately and populate your entities (or return null if no row with the given ID exists).

Note that when you are using proxies you can populate your entities on-demand within the same session. As soon as a non-id property is accessed the according entity is selected from the database.

That said, I recommend to take a look at the Hibernate docs for a better understanding. If you want to work with Hibernate on a production level you should also read a good Hibernate book like Java Persistence with Hibernate.

Hope this helps.

I have two Entities with the same name, but in different package. For me it is obvious that should work. There is no duplicated name for entities.

But I am getting an error:

Caused by: org.hibernate.AnnotationException: Use of the same entity name twice: Variant

I found solution, that tells me to use string value as Parameter for name attribute of @Entity annotation, f.e.:

@Entity(name="legal_Variant")

But I don't like to use Strings in code. Can it be done other way? F.e. using java reflection, or configuring somehow JPA to use whole name (with package name)?

For me it is quite strange. I thought that JPA takes care of package name also.

My classes code:

package insurance.models.liability.hiv;
@Entity
@Table(name="lLiability_Part_Hiv_Var")
public class Variant extends GenericDictionary<Variant> {
}

package insurance.models.liability.legal;
@Entity
@Table(name="liability_Part_Legal_Var")
public class Variant extends GenericDictionary<Variant> {}

It can be done in the mapping file:

<hibernate-mapping>
    <import class="insurance.models.liability.legal.Variant" rename="Var1" />
</hibernate-mapping>

You can now use an HQL query such as

from Var1 

Reference: Java Persistence with Hibernate (Chapter 4 pag.173/174)

I'm having a little problem setting up my webshop project. Thing is, I have a User() superclass and two subclasses, PrivateUser and BusinessUser.

Now, I'm not quite sure how to get my head around storing this relationship via hibernate.

For the purpose of this question, the User() class contains only one field:
String address;

the PrivateUser contains:
String firstName;

and the BusinessUser contains:
String CompanyName;

Each field has its getter and setter. As is right now, I would only store and be able to get firstName and companyName. When I fetch a user from my DB using Hibernate I would get a PrivateUser/BusinessUser with a null address.

Bottom line is, could someone point me towards a useful tutorial or better yet show a similar example code?

Thanks!

The Hibernate online documentation has some very good information on mapping your classes, in particular this section on setting up subclasses:

http://docs.jboss.org/hibernate/stable/core/manual/en/html/mapping.html#mapping-declaration-subclass

You want to pay special attention to using discriminator values and such if you are storing your sub-classed objects in a common table.

You might also consider picking up a copy of Java Persistence with Hibernate, which is considered the "Hibernate Bible" amongst my co-workers.

http://www.amazon.com/Java-Persistence-Hibernate-Christian-Bauer/dp/1932394885/ref=sr_1_1?ie=UTF8&s=books&qid=1272501916&sr=8-1

I wonder if it's possible to define Set in Hibernate mapping in a such way, that element would specify not column in original (FOO) table, but in joined one (BAR). Let's say we have some FooContainer.hbm.xml, which contains Set of Foo objects:

<set ...>
  <key column="COLUMN_FROM_BAR" />
  <one-to-many class="xyz.Foo" />
</set>

Here FOO has FK to BAR (FOO.BAR_ID), so joining is done through element in Foo.hbm.xml:

<many-to-one class="xyz.Bar" fetch="join" column="BAR_ID" foreign-key="barId" ... />

which results in joined FOO-BAR select whenever xyz.Foo is fetched.

Problem is that where condition of generated Set fetching select is something like:

... WHERE _FOO_0.COLUMN_FROM_BAR = ?

when desired one is:

... WHERE _BAR_0.COLUMN_FROM_BAR = ?

Found the answer in Java Persistence with Hibernate (page 296). Trick is setting different set table (BAR) from target class (Foo):

  <set table="BAR" ...>
    <key column="COLUMN_FROM_BAR" /> 
    <many-to-many
      class="xyz.Foo"
      column="BAR_ID"
      unique="true"
      />
  </set>

can use JPA and Hibernate in the same time? in the netbeans IDE ,I can create a project by mentioning the framework used hibernate,and then create a proprities.xml files to configure the mapping!

You should really try to get some basic understanding of what Hibernate is first. The Java Persistence API (JPA) is a specification defined in JSR 220 and JSR 317 (JPA 2.0). Hibernate is a JPA provider, i.e. Hibernate is an implementation of the JPA specification.

As a starting point you can take a look at this JPA Wikipedia article. You can find lots of Hibernate documentation online, but to get a deeper understanding of Hibernate I strongly recommend to read the book Java Persistence with Hibernate.