-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: JPA2 CriteriaQuery & @NaturalId
PostPosted: Wed Sep 21, 2011 11:58 pm 
Beginner
Beginner

Joined: Thu Oct 06, 2005 7:34 pm
Posts: 20
Is there any way to get a JPA2 CriteriaQuery to play nice with @NaturalId or does that just automatically happen?

I'm using Hibernate 3.6.5 with JPA2 type-safe queries, all of my objects have @NaturalId field(s) which are used quite a bit in the application to lookup the objects. I know for the Hibernate critery query you have to tell the query builder that you are doing a natural id query but I can't see a way to do that via the JPA2 CriteriaQuery API.

Data object snippet:
Code:
class PortletDefinitionImpl implements IPortletDefinition {
    @Id
    @GeneratedValue(generator = "UP_PORTLET_DEF_GEN")
    @Column(name = "PORTLET_DEF_ID")
    private final long internalPortletDefinitionId;

    @NaturalId
    @Column(name = "PORTLET_FNAME", length = 255, nullable = false)
    private String fname;

    ...
}


DAO Query Creation snippet:

Code:
        final CriteriaQuery<PortletDefinitionImpl> criteriaQuery = cb.createQuery(PortletDefinitionImpl.class);
        final Root<PortletDefinitionImpl> definitionRoot = criteriaQuery.from(PortletDefinitionImpl.class);
        criteriaQuery.select(definitionRoot);
        criteriaQuery.where(
            cb.equal(definitionRoot.get(PortletDefinitionImpl_.fname), this.fnameParameter)
        );


Does hibernate just figure out that this is a query using the NaturalId or is there more I need to do? I don't see any related hints in QueryHints.


Top
 Profile  
 
 Post subject: Re: JPA2 CriteriaQuery & @NaturalId
PostPosted: Thu Sep 22, 2011 12:48 am 
Beginner
Beginner

Joined: Thu Oct 06, 2005 7:34 pm
Posts: 20
From what I can tell by setting some break points in Loader it appears that Hibernate does not automatically figure out that the JPA2 CriteriaQuery is using the NaturalId columns. I'm looking at the hibernate code a bit and wondering if this is doable with a small patch to add a new query hint.


Top
 Profile  
 
 Post subject: Re: JPA2 CriteriaQuery & @NaturalId
PostPosted: Sat Sep 24, 2011 10:13 pm 
Beginner
Beginner

Joined: Thu Oct 06, 2005 7:34 pm
Posts: 20
So until I get more time to figure a patch to add a NaturalId hint to the JPA2 CriteraQuery I'm doing the following in the abstract DAO class we use. At least this way we can still use the the type-safe features of the JPA2 meta-model when building the non-type-safe Critera.

Code:
public <T> NaturalIdQueryBuilder<T> createNaturalIdQuery(Class<T> entityType, String cacheRegion) {
    final Session session = entityManager.unwrap(Session.class);
    return new NaturalIdQueryBuilder<T>(session, entityType, cacheRegion);
}

public static class NaturalIdQueryBuilder<T> {
    private final Class<T> entityType;
    private final Criteria criteria;
    private final NaturalIdentifier naturalIdRestriction;
   
    private NaturalIdQueryBuilder(Session session, Class<T> entityType, String cacheRegion) {
        this.entityType = entityType;
        this.criteria = session.createCriteria(this.entityType);
        this.criteria.setCacheable(true);
        this.criteria.setCacheRegion(cacheRegion);
       
        this.naturalIdRestriction = Restrictions.naturalId();
    }
   
    public <V> NaturalIdQueryBuilder<T> setNaturalIdParam(Attribute<T, V> attribute, V value) {
        final Class<V> valueType = attribute.getJavaType();
        this.naturalIdRestriction.set(attribute.getName(), valueType.cast(value));
        return this;
    }
   
    public T execute() {
        this.criteria.add(this.naturalIdRestriction);
        return this.entityType.cast(criteria.uniqueResult());
    }
}



Usage Example:
Code:
final NaturalIdQueryBuilder<PortletDefinitionImpl> naturalIdQuery = this.createNaturalIdQuery(PortletDefinitionImpl.class, FIND_PORTLET_DEF_BY_FNAME_CACHE_REGION);
naturalIdQuery.setNaturalIdParam(PortletDefinitionImpl_.fname, fname);

return naturalIdQuery.execute();


Top
 Profile  
 
 Post subject: Re: JPA2 CriteriaQuery & @NaturalId
PostPosted: Sun Sep 25, 2011 12:00 am 
Beginner
Beginner

Joined: Thu Oct 06, 2005 7:34 pm
Posts: 20
Though now I realize that I'm going to be bitten by https://hibernate.onjira.com/browse/HHH-4838 for 3/4 of my objects as they have eagerly fetched associations and child objects which results in hibernate not correctly figuring out that the query is a natural id query.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.