Saturday, November 15, 2008

Hibernate Faqs

What is Hibernate?

Hibernate is a powerful, high performance object/relational persistence and query service. This lets the users to develop persistent classes following object-oriented principles such as association, inheritance, polymorphism, composition, and collections.

What is ORM?

ORM stands for Object/Relational mapping. It is the programmed and translucent perseverance of objects in a Java application in to the tables of a relational database using the metadata that describes the mapping between the objects and the database. It works by transforming the data from one representation to another.

What does an ORM solution comprises of?

It should have an API for performing basic CRUD (Create, Read, Update, Delete) operations on objects of persistent classes

Should have a language or an API for specifying queries that refer to the classes and the properties of classes

An ability for specifying mapping metadata

It should have a technique for ORM implementation to interact with transactional objects to perform dirty checking, lazy association fetching, and other optimization functions

What are the different levels of ORM quality?

There are four levels defined for ORM quality.

Pure relational

Light object mapping

Medium object mapping

Full object mapping

What is a pure relational ORM?

The entire application, including the user interface, is designed around the relational model and SQL-based relational operations.

What is a meant by light object mapping?

The entities are represented as classes that are mapped manually to the relational tables. The code is hidden from the business logic using specific design patterns. This approach is successful for applications with a less number of entities, or applications with common, metadata-driven data models. This approach is most known to all.

What is a hibernate xml mapping document and how does it look like?

In order to make most of the things work in hibernate, usually the information is provided in an xml document. This document is called as xml mapping document. The document defines, among other things, how properties of the user defined persistence classes’ map to the columns of the relative tables in database.

Everything should be included under tag. This is the main tag for an xml mapping document.

What the Core interfaces are of hibernate framework?

There are many benefits from these. Out of which the following are the most important one.

Session Interface – This is the primary interface used by hibernate applications. The instances of this interface are lightweight and are inexpensive to create and destroy. Hibernate sessions are not thread safe.

SessionFactory Interface – This is a factory that delivers the session objects to hibernate application. Generally there will be a single SessionFactory for the whole application and it will be shared among all the application threads.

Configuration Interface – This interface is used to configure and bootstrap hibernate. The instance of this interface is used by the application in order to specify the location of hibernate specific mapping documents.

Transaction Interface – This is an optional interface but the above three interfaces are mandatory in each and every application. This interface abstracts the code from any kind of transaction implementations such as JDBC transaction, JTA transaction.

Query and Criteria Interface – This interface allows the user to perform queries and also control the flow of the query execution.

What are Callback interfaces?

These interfaces are used in the application to receive a notification when some object events occur. Like when an object is loaded, saved or deleted. There is no need to implement callbacks in hibernate applications, but they’re useful for implementing certain kinds of generic functionality.

Can I rollback after a session.flush() ?

Definitely YES! Flushing the session means executing SQL like you do in plain JDBC. It has absolutely no relationship with transaction. Actually Hibernate can flush session behind your back.

I have CGLIB / reflection optimizer errors or similar when migrating from 2.1 betaX to 2.1 rc1.

Symptoms may be :

* java.lang.NoClassDefFoundError during Configuration.buildSessionFactory

* java.lang.IllegalAccessError in net.sf.cglib.core.ClassEmitter.setTarget

* java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.visitMethod(ILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;)Lorg/objectweb/asm/CodeVisitor;

hibernate 2.1 rc1 and above now use CGLIB 2. Remove your old CGLIB jar from your classpath and replace it with the one shipped with hibernate2 (./lib/cglib2.jar).

I've followed the above instructions and I'm still having CGLIB problems in 2.1 Final.

Examples are:

Caused by: java.lang.NoSuchMethodException: java.sql.Statement.execute(java.lang.String, [B)

at java.lang.Class.getDeclaredMethod(Class.java:1256)

at java.sql.PreparedStatement$$EnhancerByCGLIB$$3c240523.()

Caused by: java.lang.ClassFormatError: Illegal Field name "CGLIB$load_class$ARRAY0$_Ljava_lang_String;"

at java.lang.ClassLoader.defineClass0(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:537)

Both of these exceptions are from bugs in the CGLIB 2.0 RC1 library included with Hibernate 2.1 Final. They have been fixed in CGLIB 2.0 RC2, which may be downloaded here:

http://prdownloads.sourceforge.net/cglib/cglib-full-2.0-RC2.jar?download

This updated jar file will be included with the next release of Hibernate.

Related forum threads are here:

http://forum.hibernate.org/viewtopic.php?t=925978

http://forum.hibernate.org/viewtopic.php?t=926299

Storing Big5 or Unicode Strings

Data has some String fields that stores Chinese Big5 encoding String , ex: Title and Description; I use DAO pattern , and in the implementation code , when persisting 'Data', I have to manually change the String encoding from Big5 to 8859_1 to be able to store it to MySQL. I found the final solution:

In hibernate.cfg.xml:

jdbc:mysql://host/db?useUnicode=true&characterEncoding=Big5

Both uneUnicode = true , and characterEncoding=Big5 are needed and make sure to 'escape' the '&' character.

I've got problems with legacy tables with UPPERCASE/lowercase identifiers

You can easily quote the table names in the mapping file, using backticks:

I've got problems with WebLogic and JNDI, how does it work?

This forum believe there's some problem if you do it the regular way like most app server. Therefore, try the following (which works for me). Use a WLS Startup class to bind Hibernate Session Factory object in WLS JNDI. Here's an excerpt of a possible code:

public class WLSStartup implements T3StartupDef

{

public static final String SESSION_FACTORY_JNDI = "hibernate";

public static final String URL = "t3://localhost:7001";

/**

* Called by WebLogic server upon startup. This is where everything should

* be initialzed.

*

* @param name the JNDI name of this class

* @param args any input parameters

*

* @return the status.

*

* @throws Exception in case of any error

*/

public String startup( String name, Hashtable args ) throws Exception

{

String METHOD_NAME = "startup ";

// Bind the various Hibernate Object to the Weblogic JNDI

try

{

log ( METHOD_NAME + " Going to bind Hibernate object. " );

doBind( );

log ( METHOD_NAME + " Bound Hibernate object!" );

}

catch ( Exception exception )

{

log ( METHOD_NAME + " Exception while binding Hibernate Object to Weblogic JNDI" );

exception.printStackTrace ( );

}

return "WLS Startup completed successfully";

}

/**

* Performs Hibernate objects to Weblogic JNDI Namespace bindings.

* It gets the initial context and binds the Hibernate objects to it.

*

* @param None

* @throws Exception in case of any errors

*/

private static void doBind( ) throws Exception

{

Properties environment = null;

InitialContext context = null;

try

{

//Properties for storing JNDI configuration information

environment = new Properties( );

//Add initial context factory

environment.put( Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");

environment.put( Context.PROVIDER_URL, URL );

log( "Constructing an Initial Directory Context object" );

context = new InitialContext( environment );

Datastore ds = Hibernate.createDatastore();

SessionFactory factory = ds.buildSessionFactory();

if (factory == null)

throw new Exception("SessionFactory cannot be built?!");

try

{

if( context.lookup(SESSION_FACTORY_JNDI ) != null )

context.rebind(SESSION_FACTORY_JNDI, factory );

else

context.bind(SESSION_FACTORY_JNDI, factory );

}

catch ( NamingException nameEx )

{

context.bind(SESSION_FACTORY_JNDI, factory );

}

}

catch ( NamingException nameExp )

{

throw new Exception( "NamingException: " + nameExp.getMessage( ));

}

catch( Exception excp )

{

throw excp;

}

finally

{

if( context != null )

{

try

{

context.close( );

context = null;

}

catch ( NamingException nameExp )

{

throw new Exception( "NamingException for context close: " nameExp.getMessage( ));

}

}

environment = null;

}

}

Jar up the relevant Hibernate jar files and configure this Startup class under WLS console.

Then at your JNDI client (Servlet or EJBs for example) you can have a code similar to this excerpt below: -

Object objref;

Context context;

Hibernate.configure();

//The usual WLS JNDI context

context = getInitialContext();

objref = context.lookup(WLSStartup.SESSION_FACTORY_JNDI);

sessionFac = (SessionFactory) PortableRemoteObject.narrow(objref, SessionFactory.class);

if sessionFac == null)

throw new Exception("Null SessionFactory found?!");

Works great with Struts 1.1 on WLS 6.X and 7.X. I've tested by writing some subclass relationship data into Oracle 8i!

Any questions can be directed to simon@see-consulting.com.

MS SQL Server with JSQLConnect driver throws exception with delete()

Hibernate 2.0.1 propagates an exception from Session.flush() following Session.delete(Object):

net.sf.hibernate.HibernateException: SQL update or deletion failed (row not found)

at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:25)

NonBatchingBatcher.addToBatch expects PreparedStatement.executeUpdate() to return 1, but it returns 0 in this case, even though it has deleted 1 row from the database.

I solved this problem by appending "/lastUpdateCount=true" to the JDBC url for JSQLConnect. This makes the JDBC driver behave as Hibernate expects. Without this property, it seems the driver returned the number of rows updated by a trigger that was executed as a side-effect of the requested change. See http://www.j-netdirect.com/JSQLConnect/TechnicalReference.html#ConnectSettings for more information.

Should I GROUP BY all object attributes in HQL?

At present you need to explicitly enumerate all the employee properties in the GROUP BY. This might be a wrinkle in HQL, or it might actually be OK.

SELECT e

FROM Employee e

LEFT JOIN Customer c AS c.staff.id

WHERE e.team.id = :id

GROUP BY e.firstName, e.lastName, e.salary

ORDER BY count(c.staff.id) ASC

"Flush during cascade is dangerous" with own equals() method

When you delete child object from collection like described in documentation and

* Use proxy for you persistent class

* Overwrite equals method for your class

* Use class comparison checking in your equals() like this

if( !(o.getClass() == getClass()) ) return false;

You may get an error because both classes are not identical. Use instanceof instead.

How to handle transactions that span multiple data access objects?

Consider a business controller that needs to delegate to 2 DAOs for a certain use case. The processing is supposed to occur within a single transaction. How to inform your DAOs that they need to participate in the surrounding transaction, instead of opening their own Hibernate Session? And how to make them run in their individual transactions else?

Passing around a Session instance as parameter to the DAO methods is not desirable, as such a required parameter is inconvenient, and the DAO interfaces should not be Hibernate-specific. A RYO solution according to the ThreadLocal Session pattern will work but tie the business controllers to Hibernate for transaction demarcation.

The goal is to make DAO interfaces agnostic of both the data access mechanism of an implementation and the actual transaction strategy of the caller. This allows for e.g. mixing Hibernate DAOs and plain JDBC DAOs with either native Hibernate transactions or JTA. A generic transaction mechanism is needed, with support for passing thread-bound Hibernate Sessions or JDBC Connections or whatever.

The Spring Framework provides such generic transaction management in a very lightweight way, with first-class support for Hibernate, backed by either native transactions or JTA. There is also respective support for JDO and plain JDBC. Transactions can be demarcated either programmatically or declaratively via an AOP interceptor. The generic management helps to avoid tying business objects to a particular transaction strategy.

Furthermore, Spring's lightweight bean container offers means for wiring up an application, e.g. a middle tier that consists of business objects, data access objects, and resources. Spring also provides generic AOP support within the bean container, and sophisticated convenience support for plain JDBC access. Note that Spring's individual parts can be reused on their own easily, as they are as loosely coupled as possible.

Data Access with the Spring Framework

What is the precedence for the methods in the Lifecycle and Interceptor interfaces?

Save or Update:

* Interceptor.isUnsaved

Save:

* Lifecycle.onSave

* Interceptor.onSave

Update:

* Lifecycle.onUpdate

Load:

* Interceptor.onLoad

* Lifecycle.onLoad

Delete:

* Interceptor.onDelete

* Lifecycle.onDelete

Flush:

* Interceptor.preFlush

* Interceptor.findDirty

* Interceptor.onFluchDirty

* Interceptor.postFlush

Hibernate startup is slow, what can I do?

I just discovered the new cglib version available at cglib.sf.net. Using the new library has cut my Hibernate startup configuration times from sometimes 3 minutes (I had over 70 persistent classes) to nearly nothing. This has been a godsend, given the nature of the app is that it has to be restarted for every code change -- debugging could be a nightmare.

If not allready done could you (Gavin) start packaging this newer version with Hibernate -- it's a real time saver.

Luke Monahan

You need to remove bcel.jar from classpath and use asm.jar for performance ( BCEL has priority in cglib 1.0 ). We will drop BCEL in the next version.

Juozas Baliuka

MS SQL performance and unicode (indexing of VARCHARs)

Am I the only person in the world who didn't know what happens if you use VARCHAR's with Java and the MS SQL JDBC driver? It seems unlikely because I can find no mention of this in the list archives or the like. If you use VARCHARs for database tables and index those columns either (as a primary key or not) , then you will find that without this option

sendStringParametersAsUnicode=false

set on the JDBC driver string, all queries will use a table scan rather than the index to access rows. This is somewhat annoying with large tables (as you can imagine). The reason is that the JDBC driver marks the string as an NVARCHAR so when the execution plan is created, it includes the conversion of the row's VARCHAR to an NVARCHAR. This stops SQL Server from using an index and you end up with a very slow query.

What gets even more annoying (and potentially confusing) is that this does not happen with direct queries, only prepared statements (hence the issue with hibernate). It might be wise to make note of this fact in the FAQ or documentation. I only found 1 article on google in a news group that mentions this (and I am indebted to that person for enlightening me...)

The article: on Google Groups

From: Gary Evesson

I'm getting a java.lang.ExceptionInInitializerError with JDK 1.3

Hibernate is build with the latest stable JDK 1.4, this error may be a binary incompatibility with JDK 1.3. Recompile the hibernate.jar (ant jar) with JDK 1.3. It looks like this is a combination/issue with both Tomcat and the JDK. Here's the old thread: http://sourceforge.net/forum/message.php?msg_id=2062040

If anyone is able to reproduce and debug this issue, please add to this FAQ entry.

Follow up:

Hi, we are a develop team at Universidad de las Americas, Puebla in Mexico and

we got the same problem trying to run a web app using hiberante, the app was developed using JSDK 1.4, but in the real enviroment it was suposed to run on a JSDK 1.3, all we did to get it running was:

1) upgraded to the last stable version of the 1.3 platform

2) recompiled the hiberante source with this version (all though any 1.3 version seems to do fine)

3) get the apropiate jdbc drivers for the jsdk and database

and that's it, the app is running on a JSDK 1.3 enviroment using all the virtuous functions in hibernate :)

I'm getting "Too many tables. MySQL can only use 31 tables in a join"

You can set outer-join="false" on associations or, in Hibernate 2.1, use hibernate.max_fetch_depth.

Websphere 5 produces a com.ibm.websphere.ce.cm.StaleConnectionException: Connection is closed

Unfortunately on WebSphere 5.0 I get the following error message when closing a Hibernate Session:

net.sf.hibernate.util.JDBCExceptionReporter TRAS0014I: The following exception was logged com.ibm.websphere.ce.cm.StaleConnectionException: Connection is closed

We had this same problem with data source connections in Websphere. We "fixed" it by configuring the data source to "Disable auto connection cleanup". It's a checkbox in the data source setup in Websphere.

What are the rules for the SQL String passed in the new createSQLQuery"

There is an excellent thread about this, see http://forum.hibernate.org/viewtopic.php?t=418

Rules:

#01: All of the columns must be specified, either via {alais1}.* or by explicitly listing each.

[to be continued]

Hibernate crashes on this Sun RAQ server. What gives?

The problem with most Sun RAQs is that they are loaded with pretty old (and I guess stable) versions of Java (version 1.3 is old now, OK?!). The problem here is related to a FAQ above in that you get some really odd null pointer exceptions, e.g. when creating the session factory or when hydrating a rowset back into an object. The solution is simple: rebuild hibernate with a similar version of Java to the one on the server. In most cases this is just a case of installing the old version of Java and then setting JAVA_HOME to point to the old Java before running the hibernate build script (shipped with the distribution).

From: Russ Freeman

Invalid parameter exceptions listed when an object mapping is read

Although the documentation suggests that object properties can be public, private or protected, there is still a restriction on accessing non-public properties via reflection when using a JDK <>

From: Russ Freeman

Can I disable the Session cache?

You can't disable it, because that would expose you to stack overflows where there are circular references, etc.

You can, however, either clear() it, or change the FlushMode.

Issues with MS SQL Server UID (GUIDs)

MS SQL Server UID is a data type of 16-bytes binary values that operate as globally unique identifiers (GUIDs).

In character string format the UID looks like this: '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'

I found that this data type could cause some problems when used in i.e. loading an object from the database.

The following two examples will both have the same result:

session.load(MyObject.class, "{2C90AA1E-00F8-00F8-0001-FFFFF8F40C12}");

, and:

session.load(MyObject.class, "2C90AA1E-00F8-00F8-0001-FFFFF8F40C12");

MS SQL Server seems to remove the brackets from the UID when querying the database. When using this together with Apache JCS the difference between using brackets and not using brackets is crucial!

Suppose that MyObject have a one-to-many relationship to MyOtherObject, and this relationship is bi-directional (MyOtherObject have a reference to its parent MyObject).

When loading MyObject from database with an UID including brackets, Apache JCS will store this UID (with brackets) as the key used for locating the object in cache. This will cause the related object, MyOtherObject, not finding its parent (MyObject) in the cache and therefore load another instance of the parent MyObject into the cache.

The reason for this is; MyOtherObject will have a reference to the parent defined as an foreign key in the database. When MyOtherObject will get loaded it will try to lookup its parent by an UID without brackets!

Since we specified to load MyObject by an UID with brackets you wont get a hit in the cache cause MS SQL Server returns the UID from database without brackets. A new instance of MyObject will be created and its key in Apache JCS will be a UID without the brackets.

Now we have two instances of the parent MyObject in Apache JCS, one located by its UID with brackets and another located by its UID without brackets.

If you load MyObject by its UID with brackets, change the state of the object and then tries to persist the changes to database - it just wont happen!

One UPDATE will be performed cause you have changed the state of the instance MyObject stored in Apache JCS located by its UID with brackets, another UPDATE on the related instance MyOtherObject will be performed, and another UPDATE on MyObject will be performed - on the other instance to MyObject handled by MyOtherObject. This instance have not been changed but is different from the instance of MyObject located by its UID with brackets and therefor be persisted into the database with its old values. And since MS SQL Server sees the UID with or without the brackets as same, the updated row in database with the new values will be overwriten with the old values!

REMEBER! An UID with brackets or without brackets is handled the same by MS SQL Server, but NOT by Apache JCS.

21.

What does hibernate.properties file consist of?

This is a property file that should be placed in application class path. So when the Configuration object is created, hibernate is first initialized. At this moment the application will automatically detect and read this hibernate.properties file.

hibernate.connection.datasource = java:/comp/env/jdbc/AuctionDB

hibernate.transaction.factory_class =

net.sf.hibernate.transaction.JTATransactionFactory

hibernate.transaction.manager_lookup_class =

net.sf.hibernate.transaction.JBossTransactionManagerLookup

hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect

What should SessionFactory be placed so that it can be easily accessed?

As far as it is compared to J2EE environment, if the SessionFactory is placed in JNDI then it can be easily accessed and shared between different threads and various components that are hibernate aware. You can set the SessionFactory to a JNDI by configuring a property hibernate.session_factory_name in the hibernate.properties file.

What are POJOs?

POJO stands for plain old java objects. These are just basic JavaBeans that have defined setter and getter methods for all the properties that are there in that bean. Besides they can also have some business logic related to that property. Hibernate applications works efficiently with POJOs rather then simple java classes.

What is object/relational mapping metadata?

ORM tools require a metadata format for the application to specify the mapping between classes and tables, properties and columns, associations and foreign keys, Java types and SQL types. This information is called the object/relational mapping metadata. It defines the transformation between the different data type systems and relationship representations.

What is HQL?

HQL stands for Hibernate Query Language. Hibernate allows the user to express queries in its own portable SQL extension and this is called as HQL. It also allows the user to express in native SQL.

What are the different types of property and class mappings?

Typical and most common property mapping

Or

Derived properties

Typical and most common property mapping

Controlling inserts and updates

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

What is Attribute Oriented Programming?

XDoclet has brought the concept of attribute-oriented programming to Java. Until JDK 1.5, the Java language had no support for annotations; now XDoclet uses the Javadoc tag format (@attribute) to specify class-, field-, or method-level metadata attributes. These attributes are used to generate hibernate mapping file automatically when the application is built. This kind of programming that works on attributes is called as Attribute Oriented Programming.

What are the different methods of identifying an object?

There are three methods by which an object can be identified.

Object identity –Objects are identical if they reside in the same memory location in the JVM. This can be checked by using the = = operator.

Object equality – Objects are equal if they have the same value, as defined by the equals( ) method. Classes that don’t explicitly override this method inherit the implementation defined by java.lang.Object, which compares object identity.

Database identity – Objects stored in a relational database are identical if they represent the same row or, equivalently, share the same table and primary key value.

What are the different approaches to represent an inheritance hierarchy?

Table per concrete class.

Table per class hierarchy.

Table per subclass.

What are managed associations and hibernate associations?

Associations that are related to container management persistence are called managed associations. These are bi-directional associations. Coming to hibernate associations, these are unidirectional.

Q: What is threaded programming and when is it used?

A: Threaded programming is normally used when a program is required to do more than one task at the same time. Threading is often used in applications with graphical user interfaces; a new thread may be created to do some processor-intensive work while the main thread keeps the interface responsive to human interaction.

The Java programming language has threaded programming facilities built in, so it is relatively easy to create threaded programs. However, multi-threaded programs introduce a degree of complexity that is not justified for most simple command line applications.

Q: Why are wait(), notify() and notifyall() methods defined in the Object class?

A: These methods are detailed on the Java Software Development Kit JavaDoc page for the Object class, they are to implement threaded programming for all subclasses of Object.

Q: Why are there separate wait and sleep methods?

A: The static Thread.sleep(long) method maintains control of thread execution but delays the next action until the sleep time expires. The wait method gives up control over thread execution indefinitely so that other threads can run.

0 comments:

Your Title