[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-3121) Using fetch="subselect" and second level cache causes NullPointerException

Vesa Tuononen (JIRA) noreply at atlassian.com
Fri Dec 12 17:15:39 EST 2008


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3121?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=31947#action_31947 ] 

Vesa Tuononen commented on HHH-3121:
------------------------------------

I was facing this issue in our project.
I try simplify to the main points...

High level pojo structure

Pojo1
    @ManyToOne(EAGER)
    @JoinColumn(name = "Pojo2_fk")
     Pojo2
     
Pojo2
     @OneToMany(EAGER, mappedBy="owner")
     @Fetch(FetchMode.SUBSELECT)
     Pojo3

Data in DB
Pojo1
   fieldX    Pojo2_fk
   2            1
   3            1
   4            2

And HQL  part 
Query query = session.createQuery("select Pojo1 where fieldX>1 order by fieldX");
query.setCacheable(true);
query.setFirstResult(0);
int fetchSize = 2;//  If fetchSize 3 or more all works fine
query.setFetchSize(fetchSize);
query.setMaxResults(fetchSize);
List<Pojo1> l = (List<Pojo1>) query.list();

And working workaround was change the query handling to the following mode.
Query query = session.createQuery("select Pojo1 where fieldX>1 order by fieldX");
query.setCacheable(true);
query.setFirstResult(0);
int fetchSize = 2;
query.setFetchSize(fetchSize);
//query.setMaxResults(fetchSize);
//List<Pojo1> l = (List<Pojo1>) query.list();
List<Pojo1> l = new ArrayList<Pojo1>(fetchSize);
Iterator<Pojo1> it = query.iterate();
for (int i = 0; i < fetchSize; i++) {
   if (it.hasNext()) {
      l.add(it.next());
   } else {
      break;
   }
}
      


> Using fetch="subselect" and second level cache causes NullPointerException
> --------------------------------------------------------------------------
>
>                 Key: HHH-3121
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3121
>             Project: Hibernate Core
>          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.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list