martedì 23 novembre 2010

Hibernate Generic Faqs

I get an OutOfMemoryException when I redeploy on Tomcat!

This  is common and not the fault of Hibernate or anything Hibernate does.  Hibernate has no leaking ThreadLocal variables, no classloader magic,  nothing else that has ever been identified as causing this and could be  somehow fixed in Hibernate. Tomcat's reloading of the web contexts  doesn't work reliably with other libraries (such as Struts, etc), the  reasons are often found in Tomcat, Classloaders, or JVM bugs. Please  don't post any questions about this on the Hibernate forums, or on the  Hibernate developer list. Ask on the Tomcat users list. If you need hot  redployment to work immediately, use Tomcat inside JBoss application  server.

Can I use Hibernate with JDK 1.3?

Yes,  but the distributed binaries are compiled for JDK 1.4 and newer. You  will have to recompile Hibernate from source (type 'ant' in the  distribution directory). This probably fails, as some of the  dependencies of Hibernate have been compiled or are only available for  JDK 1.4 and newer. However, users reported success after they found  replacements for these dependencies.

Hibernate doesn't work with MySQL!

The  MySQL Server 4.1.12 RPM delivered with Mandriva Linux 2006 breaks  prepared statements. This can be solved by either adding  "useServerPrepStmts=false" to the MySQL connection string in the  Hibernate configuration file or by using an unbroken original MySQL  Server package. http://bugs.mysql.com/bug.php?id=14910

Hibernate expects my JDBC driver to support JDBC2 but it doesn't!

Set

hibernate.jdbc.batch_size=0
hibernate.jdbc.use_scrollable_resultsets=false

or  upgrade your driver to the latest version. Hibernate chooses sensible  default values for these properties, based upon your SQL dialect.

My JDBC driver supports batch updates. How come Hibernate doesn't enable them by default?

Batch  updates seem to be cause problems for some JDBC drivers that claim to  support them. We found that batch updates should be disabled for DB2 and  Sybase.

Hibernate doesn't work with my MS SQL 2000 JDBC driver?

(Glen Stampoultzis)

If you're using Hibernate with the Microsoft SQL Server 2000 JDBC driver chances are you'll run into this problem:

java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]
Can't start a cloned connection while in manual transaction mode.

Simply add SelectMethod=Cursor; to your connection string. There's a MS knowledge base article with more information. The Microsoft SQL Server 2005 JDBC driver has been certified by JBoss Inc.

Are there known issues with Interbase / Firebird?

(Michael Jakl)

Yes. Due to some limitations in Interbase / Firebird we must use some workarounds:

Always set the size of your statement cache to zero (hibernate.statement_cache.size or hibernate.c3p0.max_statements)

If you are altering tables you should be in single user mode. This can be achieved by running gfix -shut.  It's also sufficient to have only one database connection open (eg.  immediately after starting the application). If more than one connection  is open, you will see errors like "table is in use". To restart your  database use gfix -online.

I'm having problems with Weblogic Server!

If you get CharScanner; panic: ClassNotFoundException: org.hibernate.hql.ast.HqlToken  - Hibernate 3.x includes a new query parser that doesn't run on  Weblogic - the reason is a packaging error of ANTLR in Weblogic's boot  classpath. Read the section in the Hibernate3 Migration Guide.

If you have a = javax.naming.NoInitialContextException=, this seems to solve it for Weblogic 8.1, in your Hibernate configuration:

<property name="jndi.url">t3://localhost:7001</property> 
<property name="jndi.class">weblogic.jndi.WLInitialContextFactory</property>

The JNDI implementation in WebLogic Server does not appear to support the Referenceable interface, and exhibits some rather strange behaviour when binding Serializable objects. Please direct complaints to BEA. This might affect only older versions of Weblogic.

Workarounds include using a different JNDI implementation (eg. Sun's FSContext) or using some other means of obtaining a SessionFactory.

See also Mathias' Blog!

The forum users 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.

After a while, Oracle throws this exception: too many open cursors

The Oracle JDBC driver doesn't much like to have its prepared statements cached. Disable PreparedStatement caching for the connection pool.

MySQL throws an exception: Cannot disable AUTO_COMMIT

Download the latest MySQL driver.

Tomcat throws java.lang.UnsupportedOperationException when fetching a JDBC connection

In Tomcat (maybe other situations) if you are using the built-in DBCP to as a JNDI datasource, be sure that you do not specify hibernate.connection.username or hibernate.connection.password in either hibernate.cfg.xml or hibernate.properties. DBCP does not implement the version of Datasource.getConnection() that takes a username and password.

JBoss AS complains about unclosed connections?

If  you get the message  "[org.jboss.resource.connectionmanager.CachedConnectionManager] Closing a  connection for you. Please close them yourself:  org.jboss.resource.adapter.jdbc.WrappedConnection" you are missing a  configuration setting, hibernate.connection.release_mode - set it to auto or read the reference documentation about it.

Nessun commento:

Posta un commento