[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3121?page=c...
]
Adam Brod commented on HHH-3121:
--------------------------------
The only work around I have found is to remove fetch="subselect". Using
batch-size="xxx" helps to reduce the n+1 problem, but isn't as good as
subselect for my case.
Using fetch="subselect" and second level cache causes
NullPointerException
--------------------------------------------------------------------------
Key: HHH-3121
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3121
Project: Hibernate3
Issue Type: Bug
Components: caching (L2)
Affects Versions: 3.2.6
Environment: Oracle 10g
Reporter: Adam Brod
I've been tuning some of our mappings to use fetch="subselect" to reduce
the number of DB queries. However, I have run into two cases where I get the exception
below. In both cases, I was loading a list of Videos, which are mapped to a list of other
objects. (In this example, Media is the superclass of Video.) I apologize that I
can't upload a full working example, but I will include the relevant mapping info.
<class name="Media" table="media" lazy="false"
discriminator-value="0">
<cache usage="nonstrict-read-write"/>
<id name="id" column="id" type="long">
<generator class="seqhilo"><param
name="sequence">hibernate_hi_sequence</param><param
name="max_lo">500</param></generator>
</id>
...
<list name="tags" lazy="true" table="media_tags"
cascade="save-update" fetch="subselect">
<cache usage="nonstrict-read-write"/>
<key column="media_id"/>
<list-index column="idx"/>
<many-to-many column="tag_id"
class="com.brightcove.catalog.Tag"/>
</list>
...
<subclass name="Video" lazy="false"
discriminator-value="1">
...
</subclass>
</class>
<class name="Tag" table="tag">
...
</class>
The HQL being executed is just a simple "from Video v where v.publisher_id =
:pubId".
The line of code where the exception is generated in Video.getDTO() is accessing the Tags
list:
for (Tag tag : getTags()) {
tags.add(tag.getDTO());
}
I've debugged into the Hibernate source to see where the NPE comes from
(CollectionLoadContext line 298).
if ( persister.isVersioned() ) {
versionComparator =
persister.getOwnerEntityPersister().getVersionType().getComparator();
final Object collectionOwner =
getLoadContext().getPersistenceContext().getCollectionOwner( lce.getKey(), persister );
version = getLoadContext().getPersistenceContext().getEntry( collectionOwner
).getVersion(); //NPE!
}
It seems that "collectionOwner" is null, so calling getEntry(collectionOwner)
returns null. Calling getVersion() on a null entry is what throws the NPE.
java.lang.NullPointerException
at
org.hibernate.engine.loading.CollectionLoadContext.addCollectionToCache(CollectionLoadContext.java:298)
at
org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:256)
at
org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:222)
at
org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:195)
at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:877)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:865)
at org.hibernate.loader.Loader.doQuery(Loader.java:729)
at
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.loadCollectionSubselect(Loader.java:2066)
at
org.hibernate.loader.collection.SubselectCollectionLoader.initialize(SubselectCollectionLoader.java:58)
at
org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at
org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
at
org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at
org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:109)
at org.hibernate.collection.PersistentList.size(PersistentList.java:91)
at com.brightcove.catalog.EconomicEntity.populateDTO(EconomicEntity.java:460)
at com.brightcove.catalog.Media.populateDTO(Media.java:192)
at com.brightcove.catalog.Video.populateDTO(Video.java:854)
at com.brightcove.catalog.Video.getDTO(Video.java:783)
at com.brightcove.catalog.Video.getDTO(Video.java:756)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira