Platform Specific Issues
I get an OutOfMemoryException when I redeploy on Tomcat!
Can I use Hibernate with JDK 1.3?
Hibernate doesn't work with MySQL!
Hibernate expects my JDBC driver to support JDBC2 but it doesn't!
My JDBC driver supports batch updates. How come Hibernate doesn't enable them by default?
Hibernate doesn't work with my MS SQL 2000 JDBC driver?
Are there known issues with Interbase / Firebird?
I'm having problems with Weblogic Server!
After a while, Oracle throws this exception: too many open cursors
MySQL throws an exception: Cannot disable AUTO_COMMIT
Tomcat throws java.lang.UnsupportedOperationException when fetching a JDBC connection
JBoss AS complains about unclosed connections?
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:
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.
NEW COMMENT
After a while, Oracle throws this exception: too many open...
30 Dec 2003, 17:06
dominikroblek
We are successfully using Hibernate with Oracle JDBC driver with
prepared statement cache enabled. We had to raise open cursor limit in
Oracle database as each cached prepared statement keeps one open cursor
on the database. Ask you DBA for assistance.
I need more Info about issues with Interbase / Firebird?
11 May 2005, 11:13
erick_77
Hi,
I am new using Hibernate. I tested the auctions example of Hibernate
using PostgresSQL as database, and it ran witout any trouble. But now I
need to test it with firebird, when I run the build.bat It creates the
tables but at the moment that it starts to alter table it displays
errors that tables are in use. Example:
[java] 16:31:22,869 DEBUG SchemaExport:162 - alter table
AuctionItem add constraint FK522A9BD61107FE9B foreig
key (seller) references AuctionUser
[java] 16:31:22,929 ERROR SchemaExport:168 - Unsuccessful: alter
table AuctionItem add constraint FK522A9BD61
07FE9B foreign key (seller) references AuctionUser
[java] 16:31:22,929 ERROR SchemaExport:169 - Resource Exception.
unsuccessful metadata update
[java] object AUCTIONUSER is in use
[java] Reason: unsuccessful metadata update
[java] object AUCTIONUSER is in use
I read in this page something about this issue. And the solution is that
I need to execute the firebird's gfix command. I would like to get more
information about this issue, please be more specific with your answer
or if you have another alternative way to solve it.
Thanks.
Incorrect link for JSQL
23 Sep 2005, 07:22
geofft
The link provided for JSQL is http://www.j-netdirect.com when in fact
it should be http://www.jnetdirect.com
Re: After a while, Oracle throws this exception: too many open..
20 Apr 2006, 08:10
bworwood
POST QUESTIONS ON THE FORUM! COMMENTS HERE SHOULD ADD VALUE TO THE
PAGE!On 30 Dec 2003 17:06, dominikroblek wrote:
>We are successfully using Hibernate with Oracle JDBC driver with
>prepared statement cache enabled. We had to raise open cursor limit in
>Oracle database as each cached prepared statement keeps one open
cursor
>on the database. Ask you DBA for assistance.
I am having a similar problem - open cursors are not being cleared.
Did you get over your issue?
DB2 ClassCastException when using JDBC batches
08 Sep 2006, 13:08
iamjvn
Be careful when using JDBC batch settings larger than 0.
DB2 driver with a JDBC batch size other than 0 may cause a
ClassCastException.
Caused by: java.lang.ClassCastException: java.lang.Integer
at com.ibm.db2.jcc.a.jb.a(jb.java:1068)
at com.ibm.db2.jcc.a.jb.a(jb.java:792)
at com.ibm.db2.jcc.a.jb.a(jb.java:163)
at com.ibm.db2.jcc.a.tb.a(tb.java:220)
at com.ibm.db2.jcc.b.ad.a(ad.java:1625)
at com.ibm.db2.jcc.b.ad.b(ad.java:2725)
at com.ibm.db2.jcc.b.ad.a(ad.java:2632)
at com.ibm.db2.jcc.b.ad.executeBatch(ad.java:2444)
at com.ibm.db2.jcc.b.ad.executeBatch(ad.java:1329)
at
com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
hibernate.cfg.xml
-----------------
...
...
Re: After a while, Oracle throws this exception: too many open..
25 Oct 2006, 20:06
caili314
POST QUESTIONS ON THE FORUM! COMMENTS HERE SHOULD ADD VALUE TO THE
PAGE!On 20 Apr 2006 08:10, bworwood wrote:
>POST QUESTIONS ON THE FORUM! COMMENTS HERE SHOULD ADD VALUE TO THE
>PAGE!On 30 Dec 2003 17:06, dominikroblek wrote:
>>We are successfully using Hibernate with Oracle JDBC driver with
>>prepared statement cache enabled. We had to raise open cursor limit in
>>Oracle database as each cached prepared statement keeps one open
>cursor
>>on the database. Ask you DBA for assistance.
>I am having a similar problem - open cursors are not being cleared.
>Did you get over your issue?
I ran into the same problem when using DBCP connection provider in
Hibernate 2.1.2. Traced into
net.sf.hibernate.connection.DBCPConnectionProvider, I found the
construction of statementPool didn't pass in maxTotal parameter, which
is used by GenericKeyedObjectPoolFactory to determine when to clear the
pool content. So the solutions can be either to pass in this parameter
or to disable statement pool by simply setting statemPool to null. Both
work!
Incorrect FAQ regarding Batch updates against DB2
23 Mar 2007, 00:00
anshuld
This FAQ above (#ABCD6) regarding batch
updates should be disabled against DB2 is incorrect. Batch update works
fine when using IBM DB2 JDBC driver shipped with version 8 and version
9. Batch updates should be enabled because it provides performance
advantages to application using hibernate against DB2.
In another thread (http://www.hibernate.org/120.741.html) it shows a
stack trace with ClassCastException. This only happens if type changes
between batch elements. This can be avoided by setting connection
property deferPrepares to false. This bug was also fixed in the driver
that was shipped in early 2006.
DB2 and Blobs
20 May 2008, 21:59
sgwood
Working with Hibernate + Blobs against DB2 databases, you need to be
careful with the JDBC connection settings.
When reading the blob, you can get:
com.ibm.db2.jcc.b.SqlException: [jcc][10120][11936][3.50.152] Invalid
operation: Lob is closed. ERRORCODE=-4470, SQLSTATE=null
at com.ibm.db2.jcc.b.wc.a(wc.java:55)
at com.ibm.db2.jcc.b.wc.a(wc.java:93)
at com.ibm.db2.jcc.b.rd.d(rd.java:67)
at com.ibm.db2.jcc.b.sd.w(sd.java:202)
at com.ibm.db2.jcc.b.sd.getBinaryStream(sd.java:107)
at
org.hibernate.lob.SerializableBlob.getBinaryStream(SerializableBlob.java:39)
This was with DB2 9.5 and the db2jcc driver.
The solution was to follow the advice of
http://www.ibm.com/developerworks/forums/thread.jspa?messageID=14053553
getting to a JDBC connect string like:
jdbc:db2://localhost:50000/testDB:fullyMaterializeLobData=true;fullyMaterializeInputStreams=true;progressiveStreaming=2;progresssiveLocators=2;
Categories
- About Me (1)
- Active Directory Services (4)
- Database Interview Questions (1)
- EBOOKS (1)
- EJB Interview Questions (1)
- Excel Macros (1)
- Hibernate (5)
- Internet Tips (1)
- Java Interview Questions (4)
- JMS Interview Questions (2)
- JSP Interview Questions (1)
- Oracle (3)
- PERL (4)
- Servlet Interview Questions (1)
- Struts Interview Questions (1)
- Wallpapers (2)
- Widget Tips (1)
- Windows Vista Tweaks (8)
- Windows XP (14)
- WPS Related Documents (1)
Blog Archive
-
▼
2008
(51)
-
▼
June
(30)
- THE HACKER'S DICTIONAIRY
- Set up Gmail to work with Thunderbird (IMAP)
- IMPLMENTING QUIRKS
- PERL FOR ISAPI
- PERL AVAILABILITY AND INSTALLATION
- PERL AD MANAGEMENT
- NTFS and SHARED LEVEL PERMISSIONS IN WINDOWS OPERA...
- FLASH CACHE Integrated in Intel's & Windows Vista
- Platform Specific Issues
- Performance Q&A
- Common Problems
- Tips and Tricks
- Hibernate Users FAQ
- Adv Problems
- JMS Interview Questions 2
- JMS Interview Questions
- Database Interview Questions
- Struts Interview Questions
- EJB Interview Questions
- Servlet Interview Questions
- JSP FAQ
- Java Interview Questions
- Java Interview Questions
- Java Interview Questions2
- Java Interview Questions
- WPS Documents
- Oracle 10g Essentials
- Sybex - Oracle Database Foundations
- Oracle Database 10g A.Beginners.Guide-fly
- About Me
-
▼
June
(30)
11 June 2008
Platform Specific Issues
Self Induced Content By
Hariharan
at
12:21
0
comments
Labels: Hibernate
Performance Q&A
Performance Q&A
How does Hibernate perform?
But Hibernate uses so much runtime reflection?
Okay, so what are the advantages of reflection then?
But how does it scale?
Why not implement instance-pooling anyway?
Does Hibernate implement its functionality using a minimal number of database queries?
So why don't you provide an "official" Hibernate benchmark?
Conclusion?
How does Hibernate perform?
We claim that Hibernate performs well, in the sense that its performance is limited by the underlying JDBC driver / relational database combination. Given this, the question boils down to: does Hibernate implement its functionality using a minimal number of database queries and how can it improve performance and scalability on top of JDBC? This page hopefully answers these questions.
But Hibernate uses so much runtime reflection?
Many former C or C++ programmers prefer generated-code solutions to runtime reflection. This is usually justified by reference to the performance red-herring. However, modern JVMs implement reflection extremely efficiently and the overhead is minimal compared to the cost of disk access or IPC. Developers from other traditions (eg. Smalltalk) have always relied upon reflection to do things that C/C++ needs code-generation for.
In the very latest versions of Hibernate, "reflection" is optimised via the CGLIB runtime bytecode generation library. This means that "reflected" property get / set calls no longer carry the overhead of the Java reflection API and are actually just normal method calls. This results in a (very) small performance gain.
Okay, so what are the advantages of reflection then?
A quicker compile-build-test cycle. The advantage of this should not be understated. The philosophy of Hibernate is this: let the developer spend as little time as possible implementing persistence for the 95% of the application which is used 5% of the time. Then, later, if there are performance issues with the remaining 5%, there will be plenty of time left for hand-coding JDBC calls to improve performance of particular bottlenecks. (Most of the time Hibernate very closely approaches the performance of hand-coded JDBC anyway.)
But how does it scale?
Hibernate implements an extremely high-concurrency architecture with no resource-contention issues (apart from the obvious - contention for access to the database). This architecture scales extremely well as concurrency increases in a cluster or on a single machine.
A more difficult question is how efficiently Hibernate utilizes memory under heavy load.
Since there is no sharing of objects between concurrent threads (like EJB 2.x entity beans), and since Hibernate does not automatically do instance-pooling (unlike EJB 2.x entity beans), you might think that memory utilization would be less efficient, and this may be true to an extent. However, our experience with real Java applications is that the benefits of instance-pooling are almost negated by common Java coding style. Very often programmers create a new HashMap in ejbLoad ..... or return a new Integer from a method call .... or do some string manipulations. Furthermore, every time you load and then passivate a bean, every non-primitive field of the bean is garbage, not to mention whatever garbage the JDBC driver leaves behind. All these kinds of operations leave behind as much garbage as we avoided by doing instance-pooling.
Please note that Hibernate is not a competitor to EJB. In fact, Hibernate EntityManager and Annotations implement a persistence service for EJB 3.0 entity beans, on top of the Hibernate Core architecture.
All this leads to Hibernate not needing a locking or synchronization mechanism, in memory, or to a lock table on disk. As stated earlier, Hibernate completely relies on the database management systems ability to deal with concurrent access; the experience of the DBMS vendors in this area should be used.
The other side of scalability is downward scalability. While it wasn't designed with small devices in mind, Hibernate nevertheless has a small footprint and could be used on machines with much less memory than you would need to run an application server. If it can run a JVM and a database, it should be able to run Hibernate.
Why not implement instance-pooling anyway?
Firstly, it would be pointless. There is a lower bound to the amount of garbage Hibernate creates every time it loads or updates and object - the garbage created by getting or setting the object's properties using reflection.
More importantly, the disadvantage of instance-pooling is developers who forget to reinitialize fields each time an instance is reused. We have seen very subtle bugs in EJBs that don't reinitialize all fields in ejbCreate.
On the other hand, if there is a particular application object that is extremely expensive to create, you can easily implement your own instance pool for that class and use the version of Session.load() that takes a class instance. Just remember to return the objects to the pool every time you close the session.
Does Hibernate implement its functionality using a minimal number of database queries?
Good Question. Hibernate can make certain optimizations all the time:
Caching objects. The session is a transaction-level cache of persistent objects. You may also enable a JVM-level/cluster cache to memory and/or local disk.
Executing SQL statements later, when needed. The session never issues an INSERT or UPDATE until it is actually needed. So if an exception occurs and you need to abort the transaction, some statements will never actually be issued. Furthermore, this keeps lock times in the database as short as possible (from the late UPDATE to the transaction end).
Never updating unmodified objects. It is very common in hand-coded JDBC to see the persistent state of an object updated, just in case it changed.....for example, the user pressed the save button but may not have edited any fields. Hibernate always knows if an object's state actually changed, as long as you are inside the same (possibly very long) unit of work.
Efficient Collection Handling. Likewise, Hibernate only ever inserts/updates/deletes collection rows that actually changed.
Rolling two updates into one. As a corollary to (1) and (3), Hibernate can roll two seemingly unrelated updates of the same object into one UPDATE statement.
Updating only the modified columns. Hibernate knows exactly which columns need updating and, if you choose, will update only those columns.
Outer join fetching. Hibernate implements a very efficient outer-join fetching algorithm! In addition, you can use subselect and batch pre-fetch optimizations.
Lazy collection initialization.
Lazy object initialization. Hibernate can use runtime-generated proxies (CGLIB) or interception injected through bytecode instrumentation at build-time.
A few more (optional) features of Hibernate that your handcoded JDBC may or may not currently benefit from
second-level caching of arbitrary query results, from HQL, Criteria, and even native SQL queries
efficient PreparedStatement caching (Hibernate always uses PreparedStatement for calls to the database)
JDBC 2 style batch updates
Pluggable connection pooling
Hopefully you will agree that Hibernate approaches the parsimony of the best hand-coded JDBC object persistence. As a subscript I would add that I have rarely seen JDBC code that approaches the efficiency of the "best possible" code. By contrast it is very easy to write efficient data-access code using Hibernate.
So why don't you provide an "official" Hibernate benchmark?
Many people try to benchmark Hibernate. All public benchmarks we have seen so far had (and most still have) serious flaws.
The first category of benchmarks are trivial micro benchmarks. Hibernate of course will have an overhead in simple scenarios (loading 50.000 objects and doing nothing else is considered trivial) compared to JDBC. See this page for a critique of a trivial benchmark. If you'd like to avoid writing your own trivial and not very conclusive tests, have a look at the perftest target in Hibernate's build file. We use this target to check if a trivial performance bug slipped into the Hibernate code. You can use it to verify the JDBC overhead of Hibernate in trivial situations. But, as should be clear now, these numbers are meaningless for real application performance and scalability.
In a fair benchmark with complex data associations/joins, highly concurrent access, random updates of data in the application, real-world data set size, and utilizing other Hibernate features, you will find Hibernate perform very well. Why is there no such benchmark provided by the Hibernate developers? The first reason is trust. Why would you believe that the numbers shown by the vendor of a product, in a comparative benchmark, are true? The second reason is applicability. Certainly, a fair benchmark would show the benefits of Hibernate in a typical complete application with realistic concurrent access. However, the number of variables in any decent benchmark make it almost impossible to transfer these results into reasonable conclusions about the performance of your own application. Your application is different. (If you came here from a forum thread, think about it: instead of arguing with you about your trivial micro benchmark, we would be arguing why you don't see the same results in your application...) For these reasons we always recommend that you benchmark your application yourself. We encourage you to see performance and load testing as a natural stage in the life of your application - don't go into production with only micro benchmarks. Setting up benchmarks for your application and scenario, and helping you in this stage is in fact one of our usual
Conclusion?
It turns out that Hibernate is very fast if used properly, in highly concurrent multi-user applications with significant data sets
Self Induced Content By
Hariharan
at
12:21
0
comments
Labels: Hibernate
Common Problems
Common Problems
I get a ClassNotFoundException or NoClassDefFoundError
How do I show the bound parameter values in the SQL log?
I get a ObjectNotFoundException: No row with the given identifier exists
I get InvalidObjectException: Could not find a SessionFactory named: null
I get org.hibernate.HibernateException: CGLIB Enhancement failed:
I saved / deleted / updated an object / collection but I can't see the changes in the database!
I saved a parent object but its associated objects weren't saved to the database.
I called saveOrUpdate() or update() and got a NonUniqueObjectException!
I'm using a one-to-many association with a NOT NULL constraint on the key column and Hibernate causes constraint violations.
I'm having trouble with a bidirectional association.
I'm still having trouble!
Can't I have a bidirectional association using a List or Map?
I get a log message: Parsing XML: unknown system id
I get a log message: reflection optimizer disabled
Hibernate keeps deleting and recreating my collection!
Hibernate throws a PropertyAccessException or NullPointerException when I load or query an object!
I removed an object from a collection mapped with cascade="fghjkll" but the object was not deleted!
Hibernate updates an object in the database, when I didn't change anything!
How can I get Hibernate to persist an instance variable that does not have property accessors, or simply bypass the property accessors?
Hibernate is nontransparent because it requires me to have a default constructor which breaks the API of my class!
I'm confused about the semantics of saveOrUpdate().
I don't know if I should use save() or persist().
How does inverse="true" affect the semantics of cascade="fghjkll"?
I get a ClassCastException when using a composite identifier
I get a ClassCastException when I specify a collection sort attribute.
I have some other kind of wierd bugs.....
Does Hibernate support database views?
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.
How do I use Hibernate with CMT?
How do a write a query that returns objects based upon a WHERE clause condition applied to their collection elements?
I want to retrieve query results, one page at a time
I see a java.lang.AbstractMethodError: net/sf/hibernate/persister/AbstractEntityPersister.... at startup!
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.
I have a property named like getAFoo() / setAFoo() and Hibernate throws a PropertyNotFoundException at startup.
Hibernate tries to connect to http://hibernate.sourceforge.net at startup!
I've enabled the second-level cache and my queries are not being cached!
Hibernate returns java.sql.Date instead of java.util.Date!
What is the lifecycle of a Hibernate Session?
I'm having trouble configuring association fetching strategies...
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).
How do I show the bound parameter values in the SQL log?
Hibernate uses commons logging and the org.hibernate.type package to log values bound to prepared statements. If you are using Log4J as the logging provider underneath commons logging, set this category to TRACE level to see the values in the log. Older versions of Log4J only required the DEBUG level (there was no TRACE level). See the bundled log4j.properties in the Hibernate distribution.
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:
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="fghjkll" 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
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,
insert="false" update="false"/>
In this case, the collection-valued end of the association controls updates to the database.
Or, alternatively:
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="fghjkll" but the object was not deleted!
cascade="fghjkll" cascades the delete() operation from parent to child. If this is a one-to-many association, try using cascade="fghjkll,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
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="fghjkll"?
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
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="fghjkFoo" 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.
Self Induced Content By
Hariharan
at
12:20
0
comments
Labels: Hibernate
Tips and Tricks
--------------------------------------------------------------------------------
Tips and Tricks
How can I count the number of query results without actually returning them?
How can I find the size of a collection without initializing it?
How can I order by the size of a collection?
How can I place a condition upon a collection size?
How can I query for entities with empty collections?
How can I sort / order collection elements?
Are collections pageable?
I have a one-to-one association between two classes. Ensuring that associated objects have matching identifiers is bugprone. Is there a better way?
I have a many-to-many association between two tables, but the association table has some extra columns (apart from the foreign keys). What kind of mapping should I use?
In an MVC application, how can we ensure that all proxies and lazy collections will be initialized when the view tries to access them?
How can I bind a dynamic list of values into an in query expression?
How can I bind properties of a JavaBean to named query parameters?
Can I map an inner class?
How can I assign a default value to a property when the database column is null?
How can I trucate String data?
How can I trim spaces from String data persisted to a CHAR column?
How can I convert the type of a property to/from the database column type?
How can I get access to O/R mapping information such as table and column names at runtime?
How can I create an association to an entity without fetching that entity from the database (if I know the identifier)?
How can I retrieve the identifier of an associated object, without fetching the association?
How can I manipulate mappings at runtime?
How can I avoid n+1 SQL SELECT queries when running a Hibernate query?
I have a collection with second-level cache enabled, and Hibernate retrieves the collection elements one at a time with a SQL query per element!
How can I insert XML data into Oracle using the xmltype() function?
How can I execute arbitrary SQL using Hibernate?
I want to call an SQL function from HQL, but the HQL parser does not recognize it!
--------------------------------------------------------------------------------
How can I count the number of query results without actually returning them?
Integer count = (Integer) session.createQuery("select count(*) from ....").uniqueResult();
How can I find the size of a collection without initializing it?
Integer size = (Integer) s.createFilter( collection, "select count(*)" ).uniqueResult();
How can I order by the size of a collection?
Use a left join, together with group by
select user
from User user
left join user.messages msg
group by user
order by count(msg)
How can I place a condition upon a collection size?
If your database supports subselects:
from User user where size(user.messages) >= 1
or:
from User user where exists elements(user.messages)
If not, and in the case of a one-to-many or many-to-many association:
select user
from User user
join user.messages msg
group by user
having count(msg) >= 1
Because of the inner join, this form can't be used to return a User with zero messages, so the following form is also useful
select user
from User as user
left join user.messages as msg
group by user
having count(msg) = 0
How can I query for entities with empty collections?
from Box box
where box.balls is empty
Or, try this:
select box
from Box box
left join box.balls ball
where ball is null
How can I sort / order collection elements?
There are three different approaches:
1. Use a SortedSet or SortedMap, specifying a comparator class in the sort attribute or
2. Specify an order-by attribute of
3. Use a filter session.createFilter( collection, "order by ...." ).list()
Are collections pageable?
Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();
I have a one-to-one association between two classes. Ensuring that associated objects have matching identifiers is bugprone. Is there a better way?
parent
I have a many-to-many association between two tables, but the association table has some extra columns (apart from the foreign keys). What kind of mapping should I use?
Use a composite-element to model the association table. For example, given the following association table:
create table relationship (
fk_of_foo bigint not null,
fk_of_bar bigint not null,
multiplicity smallint,
created date )
you could use this collection mapping (inside the mapping for class Foo):
You may also use an
An alternative approach is to simply map the association table as a normal entity class with two bidirectional one-to-many associations.
In an MVC application, how can we ensure that all proxies and lazy collections will be initialized when the view tries to access them?
One possible approach is to leave the session open (and transaction uncommitted) when forwarding to the view. The session/transaction would be closed/committed after the view is rendered in, for example, a servlet filter (another example would by to use the ModelLifetime.discard() callback in Maverick). One difficulty with this approach is making sure the session/transaction is closed/rolled back if an exception occurs rendering the view.
Another approach is to simply force initialization of all needed objects using Hibernate.initialize(). This is often more straightforward than it sounds.
How can I bind a dynamic list of values into an in query expression?
Query q = s.createQuery("from foo in class Foo where foo.id in (:id_list)");
q.setParameterList("id_list", fooIdList);
List foos = q.list();
How can I bind properties of a JavaBean to named query parameters?
Query q = s.createQuery("from foo in class Foo where foo.name=:name and foo.size=:size");
q.setProperties(fooBean); // fooBean has getName() and getSize()
List foos = q.list();
Can I map an inner class?
You may persist any static inner class. You should specify the class name using the standard form ie. eg.Foo$Bar
How can I assign a default value to a property when the database column is null?
Use a UserType.
How can I trucate String data?
Use a UserType.
How can I trim spaces from String data persisted to a CHAR column?
Use a UserType.
How can I convert the type of a property to/from the database column type?
Use a UserType.
How can I get access to O/R mapping information such as table and column names at runtime?
This information is available via the Configuration object. For example, entity mappings may be obtained using Configuration.getClassMapping(). It is even possible to manipulate this metamodel at runtime and then build a new SessionFactory.
How can I create an association to an entity without fetching that entity from the database (if I know the identifier)?
If the entity is proxyable (lazy="true"), simply use load(). The following code does not result in any SELECT statement:
Item itemProxy = (Item) session.load(Item.class, itemId);
Bid bid = new Bid(user, amount, itemProxy);
session.save(bid);
How can I retrieve the identifier of an associated object, without fetching the association?
Just do it. The following code does not result in any SELECT statement, even if the item association is lazy.
Long itemId = bid.getItem().getId();
This works if getItem() returns a proxy and if you mapped the identifier property with regular accessor methods. If you enabled direct field access for the id of an Item, the Item proxy will be initialized if you call getId(). This method is then treated like any other business method of the proxy, initialization is required if it is called.
How can I manipulate mappings at runtime?
You can access (and modify) the Hibernate metamodel via the Configuration object, using getClassMapping(), getCollectionMapping(), etc.
Note that the SessionFactory is immutable and does not retain any reference to the Configuration instance, so you must re-build it if you wish to activate the modified mappings.
How can I avoid n+1 SQL SELECT queries when running a Hibernate query?
Follow the best practices guide! Ensure that all
A second way to avoid the n+1 selects problem is to use fetch="subselect" in Hibernate3.
If you are still unsure, refer to the Hibernate documentation and Hibernate in Action.
I have a collection with second-level cache enabled, and Hibernate retrieves the collection elements one at a time with a SQL query per element!
Enable second-level cache for the associated entity class. Don't cache collections of uncached entity types.
How can I insert XML data into Oracle using the xmltype() function?
Specify custom SQL INSERT (and UPDATE) statements using
You will also need to write a UserType to perform binding to/from the PreparedStatement.
How can I execute arbitrary SQL using Hibernate?
PreparedStatement ps = session.connection().prepareStatement(sqlString);
Or, if you wish to retrieve managed entity objects, use session.createSQLQuery().
Or, in Hibernate3, override generated SQL using
I want to call an SQL function from HQL, but the HQL parser does not recognize it!
Subclass your Dialect, and call registerFunction() from the constructor.
Self Induced Content By
Hariharan
at
12:18
0
comments
Labels: Hibernate
Adv Problems
Advanced Problems
I'm getting 'org.hibernate.MappingException: collection was not an association' when I try to join a collection of components with Criteria queries
I get HibernateException: Don't dereference a collection with cascade="ERTDll-delete-orphan"
I'm seeing some strange behaviour with an embedded composite identifier or when using proxies.
How do I use a custom type as a query parameter?
What column should I map the
What are bags for?
Hibernate is violating a unique constraint!
I am mixing identity id generation with another id generation strategy and Hibernate causes a not null constraint violation.
Why does Hibernate always initialize a collection when I only want to add or remove an element?
I tried to filter a query result List and recieved net.sf.hibernate.QueryException: The collection was unreferenced.
Hibernate does not return distinct results for a query with outer join fetching enabled for a collection (even if I use the distinct keyword)?
Hibernate ignores my outer-join="true" or fetch="join" setting and fetches an association lazily, using n+1 selects!
Hibernate is leaking JDBC connections!
When I leave Hibernate running overnight, I come back and find that it can no longer connect to the database.
I'm supplying my own connections to Hibernate and I see exceptions like: "too many opened cursors"
My class has two one-to-many associations to different subclasses of the same root class, but Hibernate ignores the actual concrete class when loading the associations.
How do I set up a 1-to-1 relationship as lazy?
I have a non-lazy set of entities that override equals() and Hibernate throws a NullPointerException
The query language IS NULL syntax won't work with a one-to-one association!
Does HQL support UNION (or INTERSECT)?
Does HQL support hierarchical queries (eg. Oracle CONNECT BY)?
How do I use multiple databases?
Optimistic locking doesn't seem to be working/problem with JDBC batching?
How can I provide my
Hibernate throws: Flush during cascade is dangerous.
How can I map a table (or view) with no primary key?
How can I change the identifier value of an existing instance (ie. the primary key)
Hibernate generates too many outer joins. In MySQL i get Too many tables. MySQL can only use 31 tables in a join.
When initializing a many-to-many association, Hibernate fills the collection with only proxies instead of fully initialized objects, resulting in n+1 selects!
I have enabled the second-level cache, but queries still hit the database!
Is the second-level cache enabled by default?
When I delete an object that belongs to a cached collection, the collection cache is not invalidated!
I am experiencing slow performance or low memory when inserting or querying 10000 objects
I have run into some limitations using
I have a composite key where one column holds a generated value - how can I get Hibernate to generate and assign the value?
Why doesn't Hibernate just go back to the server tier and fetch data lazily instead of throwing LazyInitializationException.
How should users actually get the underlying connection from the session to do their driver specific operations ?
I'm getting 'org.hibernate.MappingException: collection was not an association' when I try to join a collection of components with Criteria queries
Hibernate currently does not support joining a collection of components or other value types with Criteria. Use HQL or submit a patch that implements this functionality.
I get HibernateException: Don't dereference a collection with cascade="ERTDll-delete-orphan"
This will happen if you load an object with a cascade="ERTDll-delete-orphan" collection and then remove the reference to the collection. Don't replace this collection, use clear() so the orphan-deletion algorithm can detect your change.
I'm seeing some strange behaviour with an embedded composite identifier or when using proxies.
It is actually surprisingly hard to get your implementation of equals() right when proxies are enabled. You must be prepared for the possibility that that a class instance is really a proxy for that class, so you can't access instance variables directly (use the accessors).
And if you are using
How do I use a custom type as a query parameter?
Use Hibernate.custom(MyUserType.class) to obtain the Hibernate Type corresponding to your UserType or CompositeUserType.
What column should I map the
You need a seperate table column holding the array or List index (the i in foo[i])! If your relational model doesn't have an index column, use a Set instead. This seems to put people off who assume that List should just be a more convenient way of accessing an unordered collection. Hibernate collections strictly obey the actual semantics attached to the Set, List and Map interfaces. List elements don't just spontaneously rearrange themselves.
On the other hand, people who planned to use the List to emulate "bag"-style semantics have a legitimate grievance here. Fortunately you can map a List or Collection with bag semantics.
What are bags for?
A bag is an unordered, unindexed collection which can contain the same element multiple times. The Java collections framework lacks a Bag interface (though you can emulate it with a List). Hibernate lets you map properties of type List or Collection with the
Hibernate is violating a unique constraint!
Hibernate isn't quite as clever with unique constraints as it is with foreign keys. Sometimes you might need to give a little hint.
A unique constraint violation could occur if two objects are both being updated, one is "releasing" a value and the other is "obtaining" the same value. A workaround is to flush() the session manually after updating the first object and before updating the second.
(This kind of problem occurs rarely in practice.)
I am mixing identity id generation with another id generation strategy and Hibernate causes a not null constraint violation.
Hibernate uses transactional write-behind for SQL inserts. Unfortunately, write-behind is impossible for the case if identity key generation. So, if you are mixing id generation strategies, you might need to:
1. save the object referred to by the foreign key (the object that does not use identity)
2. flush() manually
3. save the object that is using identity generation
Why does Hibernate always initialize a collection when I only want to add or remove an element?
Unfortunately the collections API defines method return values that may only be computed by hitting the database. There are three exceptions to this: Hibernate can add to a declared with inverse="true" without initializing the collection; the return value must always be true.
If you want to avoid extra database traffic (ie. in performance critical code), refactor your model to use only many-to-one associations. This is almost always possible. Then use queries in place of collection access.
I tried to filter a query result List and recieved net.sf.hibernate.QueryException: The collection was unreferenced.
Collection filters are for filtering persistent collections, not query results.
Hibernate does not return distinct results for a query with outer join fetching enabled for a collection (even if I use the distinct keyword)?
First, you need to understand SQL and how OUTER JOINs work in SQL. If you do not fully understand and comprehend outer joins in SQL, do not continue reading this FAQ item but consult a SQL manual or tutorial. Otherwise you will not understand the following explanation and you will complain about this behavior on the Hibernate forum.
Typical examples that might return duplicate references of the same Order object:List result = session.createCriteria(Order.class)
.setFetchMode("lineItems", FetchMode.JOIN)
.list();
...
List result = session.createCriteria(Order.class)
.list();
List result = session.createQuery("select o from Order o left join fetch o.lineItems").list();
All of these examples produce the same SQL statement:SELECT o.*, l.* from ORDER o LEFT OUTER JOIN LINE_ITEMS l ON o.ID = l.ORDER_ID
Want to know why the duplicates are there? Look at the SQL resultset, Hibernate does not hide these duplicates on the left side of the outer joined result but returns all the duplicates of the driving table. If you have 5 orders in the database, and each order has 3 line items, the resultset will be 15 rows. The Java result list of these queries will have 15 elements, all of type Order. Only 5 Order instances will be created by Hibernate, but duplicates of the SQL resultset are preserved as duplicate references to these 5 instances. If you do not understand this last sentence, you need to read up on Java and the difference between an instance on the Java heap and a reference to such an instance.
(Why a left outer join? If you'd have an additional order with no line items, the result set would be 16 rows with NULL filling up the right side, where the line item data is for other order. You want orders even if they don't have line items, right? If not, use an inner join fetch in your HQL).
Hibernate does not filter out these duplicate references by default. Some people (not you) actually want this. How can you filter them out?
Like this:Collection result = new LinkedHashSet( session.create*(...).list() );
A LinkedHashSet filteres out duplicate references (it's a set) and it preserves insertion order (order of elements in your result). That was too easy, so you can do it in many different and more difficult ways:List result = session.createCriteria(Order.class)
.setFetchMode("lineItems", FetchMode.JOIN)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.list();
...
List result = session.createCriteria(Order.class)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.list();
List result = session.createQuery("select o from Order o left join fetch o.lineItems")
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) // Yes, really!
.list();
List result = session.createQuery("select distinct o from Order o left join fetch o.lineItems").list();
The last one is special. It looks like you are using the SQL DISTINCT keyword here. Of course, this is not SQL, this is HQL. This distinct is just a shortcut for the result transformer, in this case. Yes, in other cases an HQL distinct will translate straight into a SQL DISTINCT. Not in this case: you can not filter out duplicates at the SQL level, the very nature of a product/join forbids this - you want the duplicates or you don't get all the data you need.
All of this filtering of duplicates happens in-memory, when the resultset is marshalled into objects.
It should be also obvious why resultset row-based "limit" operations, such as setFirstResult(5) and setMaxResults(10) do not work with these kind of eager fetch queries. If you limit the resultset to a certain number of rows, you cut off data randomly. One day Hibernate might be smart enough to know that if you call setFirstResult() or setMaxResults() it should not use a join, but a second SQL SELECT. Try it, your version of Hibernate might already be smart enough. If not, write two queries, one for limiting stuff, the other for eager fetching.
Do you want to know why the example with the Criteria query did not ignore the fetch="join" setting in the mapping but HQL didn't care? Read the next FAQ item.
Hibernate ignores my outer-join="true" or fetch="join" setting and fetches an association lazily, using n+1 selects!
HQL queries always ignore the setting for outer-join or fetch="join" defined in mapping metadata. This setting applies only to associations fetched using get() or load(), Criteria queries, and graph navigation. If you need to enable eager fetching for a HQL query, use an explicit LEFT JOIN FETCH.
Note also that Hibernate 2.x does not support outer join fetching of more than one many-valued association in the same query. Hibernate 3.x allows you to create Cartesian products, even if they are slower than two separate queries.
Hibernate is leaking JDBC connections!
There are three possible reasons why Hibernate might not be closing connections
You are forgetting to call Session.close().
This is the most common cause. Consider carefully how you are handling sessions. Are you sure you create only one Session per transaction? Are you certain you close the Session even if an exception occurs (ie. in a finally block).
Hibernate issues a warning in the log when an unclosed session is garbage collected, so looking there is a good place to start.
Hibernate is doing connection pooling.
Which ConnnectionProvider are you using? If its not DatasourceConnectionProvider, then it is probably doing connection pooling. This can cause problems in certain environments. Pooling may be disabled for DriverManagerConnectionProvider by setting hibernate.connection.pool_size=0 in hibernate.properties.
You are supplying your own connection.
If you supply your own JDBC connection to SessionFactory.openSession(), Hibernate does not close it from Session.close().
In any case, you can always bypass Hibernate's Connection and transaction handling altogether. For example, the following code block shows the application managing connections and transactions manually:Session s = sf.openSession( getMyJDBCConnection() ); //supply a JDBC connection
try {
// do some work
s.connection().commit();
}
catch (Exception e) {
s.connection().rollback();
}
finally {
s.close().close(); //close the session and user-supplied JDBC connection
}
That way you can be certain that Hibernate is not to blame when you see these kinds of issues (we are already quite certain).
When I leave Hibernate running overnight, I come back and find that it can no longer connect to the database.
(This is particularly common in the case of MySQL, wich times out JDBC connections after a short time.)
You should never use Hibernate's built-in connection pooling in production; it is non-scalable and non-fault-tolerant. Instead, use DBCP or C3P0 (or, even better, an application server datasource).
I'm supplying my own connections to Hibernate and I see exceptions like: "too many opened cursors"
You must disable PreparedStatement caching by setting
hibernate.statement_cache.size=0
My class has two one-to-many associations to different subclasses of the same root class, but Hibernate ignores the actual concrete class when loading the associations.
The following mapping does not work:
....
....
You must either
use a where attribute in each
map each association to a different column of the Transaction table
map a single association and use a collection filter to retrieve instances of a particular subclass
use a table-per-concrete-class mapping strategy for the Transaction hierarchy
How do I set up a 1-to-1 relationship as lazy?
Use
Actually, you do not usually need to explicitly specify fetch and lazy. The critical bit is constrained="true".
Lazy fetching is only conceptually possible for a mandatory association since we have to hit the other table to determine whether the association is null or not!
I have a non-lazy set of entities that override equals() and Hibernate throws a NullPointerException
In certain special situations (the common one is a reflexive association) a non-lazy Set containing a persistent class that overrides equals(), or a SortedSet with a custom Comparator can cause a NullPointerException. This is a known issue that will probably not be fixed, because it is the result of an important performance optimization. The workaround is to re-map the set with lazy="true".
The query language IS NULL syntax won't work with a one-to-one association!
The following queries:FROM User u WHERE u.email IS NULL
FROM User u WHERE u.email IS NOT NULL
will not work for a one-to-one association! UseSELECT u FROM User u LEFT JOIN u.email e WHERE e IS NULL
FROM User u WHERE NOT u.email IN (FROM Email e)
instead of the simple IS NULL test. The second form cannot work for a database without subselects. UseSELECT u FROM User u INNER JOIN u.email
FROM User u WHERE u.email IN (FROM Email e)
instead of IS NOT NULL. The third form will not work for a database without subselects.
Does HQL support UNION (or INTERSECT)?
Not at this time. You may use a native SQL query for this.
Does HQL support hierarchical queries (eg. Oracle CONNECT BY)?
Not at this time. You may use a native SQL query for this.
How do I use multiple databases?
You must configure multiple SessionFactory instances.
Optimistic locking doesn't seem to be working/problem with JDBC batching?
Hibernate uses the updated row count to detect conflicting data modifications. Hibernate will automatically disable JDBC batch updates if you are using versioned data, since some JDBC drivers return incorrect values after UPDATEs (i.e. Oracle's). If you are sure that your driver works, set the hibernate.jdbc.batch_versioned_data configuration property to true.
How can I provide my
Specify an extends attribute in the subclass mapping, naming a previously mapped superclass. Use of this feature makes the ordering of the mapping documents important!
Hibernate throws: Flush during cascade is dangerous.
This almost always happens because you forgot to remove a deleted instance from an association with cascading save enabled. You should remove deleted objects from associations before flushing the session. Basically, the object you're trying to delete would be resaved to the database by it being in a collection hanging off another object. You need to remove it from other collections before deleting it.
How can I map a table (or view) with no primary key?
Every table (or even view) should have some unique key. The mathematical definition of a relation is a set of tuples. (Sets do not permit duplicate elements.) Furthermore, truly identical rows can not possibly have any meaningful semantics from the user's perspective.
In some cases it may be sensible to go as far as mapping all columns of a view as a
How can I change the identifier value of an existing instance (ie. the primary key)
It is part of the definition of a primary key that it is not only unique, but also constant throughout the life of the row. Hibernate does not, and should not, support changing identifier values.
Hibernate generates too many outer joins. In MySQL i get Too many tables. MySQL can only use 31 tables in a join.
You can set fetch="select" (or outer-join="false" in Hibernate2) on particular associations or set hibernate.max_fetch_depth to a smaller value.
When initializing a many-to-many association, Hibernate fills the collection with only proxies instead of fully initialized objects, resulting in n+1 selects!
You should set fetch="join" (or outer-join="true" in Hibernate2) on the
I have enabled the second-level cache, but queries still hit the database!
The second-level cache is used for lookup by identifier. If you want to cache query result sets, you must use the query cache. See the documentation for more information.
Is the second-level cache enabled by default?
No entities or collections will be cached in the second-level cache unless you supply
Likewise, queries are not cached in the query cache, unless you explicitly call Query.setCacheable(true), even when the query cache is enabled.
When I delete an object that belongs to a cached collection, the collection cache is not invalidated!
You must remove the deleted object from all collections it belongs to.
I am experiencing slow performance or low memory when inserting or querying 10000 objects
In Hibernate 3.0 or earlier you must manage the size of the session cache using clear() or evict(). See also:
http://www.hibernate.org/hib_docs/v3/reference/en/html/batch.html
In Hibernate 3.1, you can use StatelessSession.
Even better, try to use HQL bulk queries where possible.
I have run into some limitations using
The
So, if you have this mapping:
...
Try using the following instead:
...
So we have an identifier property holding the id of the parent entity, together with an association, mapped to the same column, with insert="false" update="false".
I have a composite key where one column holds a generated value - how can I get Hibernate to generate and assign the value?
We regard this as an extremely strange thing to want to do. If you have a generated surrogate key, why not just make it be the primary key?
However, if you must do this, you can do it by writing a CompositeUserType for the composite identifier class, and then defining a custom IdentifierGenerator that populates the generated value into the composite key class.
Why doesn't Hibernate just go back to the server tier and fetch data lazily instead of throwing LazyInitializationException.
Fetching data outside the scope of a well-defined persistence context is extremely dangerous.
Transparently fetching data from the server would expose you to:
(1) massive n+1 requests problems
(2) loss of referential integrity in your client-side object graph
(3) data aliasing problems
In some ways this idea is very similar to (but worse than) the olde EJB 1/2 idea of a "remote entity", which we all know is an evil construct that simply does not scale.
How should users actually get the underlying connection from the session to do their driver specific operations ?
A work around is the interface org.hibernate.jdbc.ConnectionWrapper, which defines exactly one method: Connection getWrappedConnection(). Two ways to use this:
(1) just call the new BorrowedConnectionProxy.getWrappedConnection method passing in the proxy
(2) cast the proxy to ConnectionWrapper, and call getWrappedConnection().
Self Induced Content By
Hariharan
at
12:15
0
comments
Labels: Hibernate