Hibernate FAQ - Common Problems

Common problems

I get a ClassNotFoundException or NoClassDefFoundError
You are missing a third-party library Hibernate needs, check lib/README.txt in the Hibernate distribution first. You need all classes that are listed as required for runtime. Another much more exotic reason might be a static initializer block of one of the needed classes (error during load) or a security-related issue (policy doesn't allow loading).

This FAQ covers basic issues you can get when using Hibernate. For more advanced topics, see XXXXX

 

I get a ClassNotFoundException or NoClassDefFoundError

You are missing a third-party library Hibernate needs, check lib/README.txt in the Hibernate distribution first. You need all classes that are listed as required for runtime. Another much more exotic reason might be a static initializer block of one of the needed classes (error during load) or a security-related issue (policy doesn't allow loading).

I get a ObjectNotFoundException: No row with the given identifier exists

This might occur if you try to load a non-proxied object with session.load() or you load a proxied object and later access the proxy. It may also occur when loading mapped collections which are not eagerly fetched. Another cause are foreign key fields that are not protected with a foreign key constraint, and now contain bogus values. Check the ids you are using for load. Validate your foreign key relationships - the database should already maintain such integrity constraints. Beware of multiple transactions within a single session. Try to stick to "one session, one transaction" rule. Especially do not use sessions after a HibernateException has been thrown.

 

I get InvalidObjectException: Could not find a SessionFactory named: null

 

This exception occurs if you try to serialize a disconnected Hibernate Session and deserialize it in a different VM, or, if the classloader has restarted, for example, during hot redeployment in your application server or web container. This is especially visible in Tomcat. In application servers, always use JNDI to store the SessionFactory, as documented. In Tomcat or other web containers, disable HttpSession serialization during context reload. This has side effects, explained in the web container's documentation.

 

I get org.hibernate.HibernateException: CGLIB Enhancement failed: <classname>?

 

If you use lazy loading with proxies (default for all classes in Hibernate 3), Hibernate needs to subclass your class at runtime. It can't do this if you have a private no-argument constructor. As per documentation, at least package visibility is required.

 

I saved / deleted / updated an object / collection but I can't see the changes in the database!

 

Hibernate will not execute any SQL until you either call Transaction.commit() (if using the Transaction API) or Session.flush() (if you are not) at the end of a session to flush your in-memory changes to the database.

 

If you are not using the Transaction API, you must then explicitly commit the transaction (by committing the JTA transaction or JDBC Connection).

 

I saved a parent object but its associated objects weren't saved to the database.

 

Associated objects must be saved explicitly by calling Session.save() (or Session.persist()) or the association must be mapped with cascade="all" or cascade="save-update" (or cascade="persist").

 

I called saveOrUpdate() or update() and got a NonUniqueObjectException!

 

The session maintains a unique mapping between persistent identity and object instance, in order to help you avoid data aliasing problems. You cannot simultaneously attach two objects with the same class and identifier to the same session.

 

The best way to avoid any possibility of this exception is to always call saveOrUpdate() at the beginning of the transaction, when the session is empty.

 

In Hibernate3, you can try using the merge() operation, which does not reattach the passed instance.

 

I'm using a one-to-many association with a NOT NULL constraint on the key column and Hibernate causes constraint violations.

 

Use a bidirectional association, mapping the many-valued end with inverse="true".

 

Or, for a unidirectional association, use <key not-null="true" ... /> in the collection mapping.

 

I'm having trouble with a bidirectional association.

 

When you update a bidirectional association you must update both ends.

 

parent.getChildren().add(child);

child.setParent(parent);

It's best to do this in an association management method of your persistent class.

 

I'm still having trouble!

 

Read the documentation! There's a detailed section about "Parent/Child Relationships" in chapter 16 of the reference documentation including code examples.

 

Can't I have a bidirectional association using a List or Map?

 

In Hibernate3,

 

<hibernate-mapping>

    <class name="Parent">

        <id name="id">

            <generator class="sequence"/>

        </id>

        <list name="children" lazy="true">

            <key column="parent_id" not-null="true"/>

            <list-index column="child_order"/>

            <one-to-many class="Child"/>

        </list>

    </class>

 

    <class name="Child">

        <id name="id">

            <generator class="sequence"/>

        </id>

        <property name="name"/>

        <many-to-one name="parent" class="Parent"

            column="parent_id" not-null="true"

            insert="false" update="false"/>

    </class>

</hibernate-mapping>

In this case, the collection-valued end of the association controls updates to the database.

 

Or, alternatively:

 

<hibernate-mapping>

    <class name="eg.Parent">

        <id name="id">

            <generator class="sequence"/>

        </id>

        <list name="children" lazy="true" inverse="true">

            <key column="parent_id" not-null="true"/>

            <list-index column="child_order"/>

            <one-to-many class="Child"/>

        </list>

    </class>

 

    <class name="eg.Child">

        <id name="id">

            <generator class="sequence"/>

        </id>

        <property name="name"/>

        <property name="childOrder"

            column="child_order" not-null="true"/>

        <many-to-one name="parent" class="Parent"

            column="parent_id" not-null="true"/>

    </class>

</hibernate-mapping>

In this alternative, you must set the value of the childOrder property yourself before making the objects persistent.

 

I get a log message: Parsing XML: unknown system id

 

Ignore it. Its quite normal when loading a mapping document as a resource.

 

I get a log message: reflection optimizer disabled

 

Thats quite okay. For some classes we can't use CGLIB for property access, so we have to fall back to reflection. This will have a very minor effect upon performance. (CGLIB's MetaClass can't access final properties or nonpublic properties.)

 

Hibernate keeps deleting and recreating my collection!

 

Unlike other Hibernate value types, Hibernate tracks actual collection instances using Java identity, ==. Your getter method should return the same collection instance as was assigned by Hibernate to the setter method (unless you don't mind the collection being removed and recreated every time the session is flushed).

 

This doesn't mean you shouldn't return a different collection if you really are replacing the current collection with a new collection with completely different elements. In certain cases, this behaviour can even be taken advantage of to increase performance.

 

Hibernate throws a PropertyAccessException or NullPointerException when I load or query an object!

 

A PropertyAccessException often occurs when the object being passed to the setter method is of the wrong type. Check your type mappings for the offending property. (To see exactly which property was the problem, you might need to disable the CGLIB reflection optimizer.) However, the most common cause of this problem is that Hibernate attempted to assign null to a property of primitive type.

 

If your object has a primitive-type property mapped to a nullable database column then you will need to use a Hibernate custom type to assign a sensible default (primitive) value for the case of a null column value. A better solution is usually to use a wrapper type for the Java property.

 

I removed an object from a collection mapped with cascade="all" but the object was not deleted!

 

cascade="all" cascades the delete() operation from parent to child. If this is a one-to-many association, try using cascade="all,delete-orphan".

 

Another solution is to model your child objects as composite elements (a kind of value type) rather than entities. Value types are always persisted or removed along with their parent entity. So you would use a <composite-element> mapping for the element class instead of a <class> mapping..

 

Hibernate updates an object in the database, when I didn't change anything!

 

This always occurs because you actually did change something! Enable Hibernate's logging to debug level and search for is dirty in the log. That will tell you exactly what property is detected to be dirty.

 

How can I get Hibernate to persist an instance variable that does not have property accessors, or simply bypass the property accessors?

 

Use access="field".

 

Hibernate is nontransparent because it requires me to have a default constructor which breaks the API of my class!

 

You may declare the constructor private. (Same goes for any property accessors.)

 

I'm confused about the semantics of saveOrUpdate().

 

Firstly, so long as you are not trying to use instances from one session in another new session, you should not need to use update() or saveOrUpdate(). Some whole applications will never use either of these methods.

 

Usually update() or saveOrUpdate() are used in the following scenario:

 

the application loads an object in the first session

the object is passed up to the UI tier

some modifications are made to the object

the object is passed back down to the business logic tier

the application persists these modifications by calling update() in a second session

saveOrUpdate() does the following:

 

if the object is already persistent in this session, do nothing

if the object has an identifier property value that indicates that it is transient and no row already exists in the database, save() it

if another object associated with the session has the same identifier, throw an exception

otherwise, update() it

I don't know if I should use save() or persist().

 

Both methods make a transient instance persistent. However, the persist() method doesn't guarantee that the identifier value will be assigned to the persistent instance immediately, the assignment might happen at flush time.

 

The persist() method also guarantees that it will not execute an INSERT statement if it is called outside of transaction boundaries. This is useful in long-running conversations with an extended Session/persistence context.

 

The save() method does not guarantee the same, it returns an identifier, and if an INSERT has to be executed to get the identifier (e.g. "identity" generator, not "sequence"), this INSERT happens immediately, no matter if you are inside or outside of a transaction. This is not good in a long-running conversation with an extended Session/persistence context.

 

How does inverse="true" affect the semantics of cascade="all"?

 

It doesn't.

 

I get a ClassCastException when using a composite identifier

 

Does the composite identifier class implement Serializable?

 

I get a ClassCastException when I specify a collection sort attribute.

 

When you first instantiate a sorted collection, it must be an instance of SortedSet, or SortedMap. Use a TreeSet or TreeMap, for example.

 

I have some other kind of wierd bugs.....

 

Carefully check the accessor methods for your persistent properties. Broken get/set pairs are a common source of bugs. Remember Hibernate might call a getter method multiple times during a session.

 

Also, make sure that a call to an accessor method couldn't do anything wierd ... like initialize a lazy collection or proxy.

 

For some classes it can be worthwhile to provide two get/set pairs for certain properties - one pair for business code and one for Hibernate.

 

Does Hibernate support database views?

 

Of course. From the point of view of Hibernate, a view is just like any other table (except that you might not be able to update or insert to a view). You can easily map a class to a view by specifying table="view_name".

 

In Hibernate3, you may even map an entity class to a SQL query result set using the <subselect> mapping element. This is useful if you are unable to define new views in your database.

 

I'm using Hibernate in a CMT session bean or BMP entity bean and I recieve an exception whenever I try to commit() the Transaction or JDBC Connection.

 

In a CMT environment, you must let the container take responsibility for transaction management. Application code must still perform all the usual Session management, ie. Session.flush(), Session.close().

 

How do I use Hibernate with CMT?

 

See Sessions and transactions.

 

How do a write a query that returns objects based upon a WHERE clause condition applied to their collection elements?

 

There are two possibilities:

 

select distinct parent

from Parent parent

join parent.children child

where child.name = :name

from Parent parent where :childId in elements(parent.children)

The first query uses a table join; the second uses a subquery. The first query allows constraints to be applied to element properties; the second does not.

 

You may not need the distinct keyword in the first query.

 

I want to retrieve query results, one page at a time

 

Use Query.setMaxResults() and Query.setFirstResult() for query paging.

 

Do not use ScrollableResults for this! In an online application, holding a database cursor open across a user interaction is extremely expensive in terms of performane.

 

I see a java.lang.AbstractMethodError: net/sf/hibernate/persister/AbstractEntityPersister.... at startup!

 

(Michael Davidovich) The problem is the -classic JVM debug option, which is present in both Jboss and IntelliJ project options, beware!

 

(Christian Bauer) Recompiling Hibernate with your JDK is the other solution.

 

I am getting a PropertyAccessException, and the error trace suggests to turn off the reflection optimizer. Howerver, it doesn't seem that I can set this in hibernate.cfg.xml.

 

Unfortunately, there are two properties which may only be set at the "system" level, ie. in hibernate.properties or using java -D. This is one of them.

 

I have a property named like getAFoo() / setAFoo() and Hibernate throws a PropertyNotFoundException at startup.

 

Use name="AFoo" as the property name in your mapping files. Don't report this issue as a bug, we know about it and we can't change it. If you insist on "first letter lowercase" naming of properties, use a custom access="my.PropertyAccessor" setting.

 

Hibernate tries to connect to http://hibernate.sourceforge.net at startup!

 

Usually you use the wrong DTD declaration in your XML mapping/configuration files. Or, this means that your XML parser does not support the EntityResolver callback that Hibernate uses to resolve the mapping DTD from inside hibernate3.jar. Either use a different XML parser, such as a recent version of Xerces, or edit your mapping documents to use a SYSTEM id instead of the PUBLIC id that we recommend in the documentation.

 

I've enabled the second-level cache and my queries are not being cached!

 

The Hibernate second-level cache is different to the Hibernate query cache. The second level cache applies when objects are retrieved using get(), load() or navigation of associations. It does not apply to query result sets. You must use the query cache to cache HQL, SQL, or criteria query result sets.

 

Hibernate returns java.sql.Date instead of java.util.Date!

 

This problem occurs usually because you compare two dates wrong. The right way to compare date and time in Java is to use aDate.getTime().equals( bDate.getTime() ), this works for java.util.Date and java.sql.Timestamp.

 

Hibernate returns a java.sql.Timestamp when retrieving information from the database, as this type can transport the additional nanosecond information. If you want to cut this off, you can write a custom UserType. This is a transparent converter. See the following thread: http://forum.hibernate.org/viewtopic.php?t=925275

 

What is the lifecycle of a Hibernate Session?

 

See Sessions and transactions.

 

I'm having trouble configuring association fetching strategies...

 

See A Short Primer On Fetching Strategies.