• Home
  • RSS Feed
  • Log in

JPA implementation patterns: Retrieving entities
Posted by Vincent Partington around lunchtime: April 3rd, 2009

Last week I talked about how to save an entity. And once we've saved an entity we'd also like to retrieve it. Compared to managing bidirectional associations or saving entities, retrieving entities is actually rather simple. So simple I doubted whether there would be much point in writing this blog ;-) . However we did use a few nice patterns when writing code for this. And I'm interested to hear what patterns you use to retrieve entities. So here is the next instalment in the series on JPA implementation patterns.

Basically, there are two ways to retrieve an entity with JPA:

  • EntityManager.find will find an entity by its id or return null when that entity does not exists.
  • If you pass a query string specified in Java Persistence Query Language to EntityManager.createQuery it will return a Query object that can then be executed to return a list of entities or a single entity.


A Query object can also be created by referring to a named query (using EntityManager.createNamedQuery), or by passing in an SQL query (using one of the three three flavours of EntityManager.createNativeQuery). And while the name implies otherwise, a Query can also be used to execute an update or delete statement.

A named query may seem like a nice way to keep the query with the entities it queries, I've found that not to work out very well. Most queries need parameters to be set with one of the variants of Query.setParameter. Keeping the query and the code that sets these parameters together makes them both easier to understand. That is why I keep them together in the DAO and shy away from using named queries.

A convention I've found to be useful is to differentiate between finding an entity and getting an entity. In the first case null is returned when an entity cannot be found, while in the latter case an exception is thrown. Using the latter method when your code expects an entity to be present prevents NullPointerExceptions from popping up later.

Finding and getting a single entity by id

An implementation of this pattern for the JpaDao base class we discussed a few blogs ago can look like this (I've included the find method for contrast):

public E findById(K id) {
	return entityManager.find(entityClass, id);
}
 
public E getById(K id) throws EntityNotFoundException {
	E entity = entityManager.find(entityClass, id);
	if (entity == null) {
		throw new EntityNotFoundException(
			"Entity " + entityClass.getName() + " with id " + id + " not found");
	}
	return entity;
}

Of course you'd also need to add this new method to the Dao interface:

E getById(K id);
 

Finding and getting a single entity with a query

A similar distinction can be made when we use a query to look for a single entity. The findOrderSubmittedAt method below will return null when the entity cannot be found by the query. The getOrderSubmittedAt method throws a NoResultException. Both methods will throw a NonUniqueResultException if more than one result is returned. To keep the getOrderSubmittedAt method consistent with the findById method we could map the NoResultException to an EntityNotFoundException. But since there are both unchecked exceptions, there is no real need.

Since these methods apply only to the Order object, there are a part of the JpaOrderDao:

public Order findOrderSubmittedAt(Date date) throws NonUniqueResultException {
	Query q = entityManager.createQuery(
		"SELECT e FROM " + entityClass.getName() + " e WHERE date = :date_at");
	q.setParameter("date_at", date);
	try {
		return (Order) q.getSingleResult();
	} catch (NoResultException exc) {
		return null;
	}
}
 
public Order getOrderSubmittedAt(Date date) throws NoResultException, NonUniqueResultException {
	Query q = entityManager.createQuery(
		"SELECT e FROM " + entityClass.getName() + " e WHERE date = :date_at");
	q.setParameter("date_at", date);
	return (Order) q.getSingleResult();
}

Adding the correct methods to the OrderDao interface is left as an exercise for the reader. ;-)

Finding multiple entities with a query

Of course we also want to be able to find more than one entity. In that case I've found there to be no useful distinction between getting and finding. The findOrdersSubmittedSince method just return a list of entities found. That list can contain zero, one or more entities. See the following code:

public List<Order> findOrdersSubmittedSince(Date date) {
	Query q = entityManager.createQuery(
			"SELECT e FROM " + entityClass.getName() + " e WHERE date >= :date_since");
	q.setParameter("date_since", date);
	return (List<Order>) q.getResultList();
}

Observant readers will note that this method was already present in the first version of the JpaOrderDao.

So while retrieving entities is pretty simple, there are a few patterns you can stick to when implementing finders and getters. Of course I'd be interested to know how you handle this in your code.

P.S. JPA 1.0 does not support it yet, but JPA 2.0 will include a Criteria API. The Criteria API will allow you to dynamically build JPA queries. Criteria queries are more flexible than string queries so you can build them depending on input in a search form. And because you define them using domain objects, they are easier to maintain as references to domain objects get refactored automatically. Unfortunately the Criteria API requires you to refer to your entity's properties by name, so your IDE will not help you when you rename those.

For a list of all the JPA implementation pattern blogs, please refer to the JPA implementation patterns wrap-up.

  • Share/Bookmark

Filed under JPA, JPA implementation patterns, Java | 16 Comments »



16 Responses to “JPA implementation patterns: Retrieving entities”



    Lars Vonk Says:
    Posted at: April 3, 2009 at 8:36 pm

    Hi Vincent,

    Problems I have with the findByXXX stuff is that it doesn’ t scale well. Especially when you provide some sort of search functionality on different properties. This means you would have to add all kinds of findByThisPropertyAndThatProperty.
    So if you suffer from lots of findByXXX methods and constantly need to add stuff to your dao interface you can apply the specification pattern. Instead of isStatisfiedby a Specification should be able to transform itself to (part of) a where clause.
    This would keep your DAO interface clean: DAO.findBySpecification(Specification). Extra bonus: The relatively small specification classes are easy to test!
    In case of JPA 2.0 or SessionFactory you could use Criteria for this, but that would leak your implementation details to the client code.



    Dave Says:
    Posted at: April 4, 2009 at 2:06 am

    I’m really appreciating this series of articles…thanks! Can I make a future article request? I’m struggling with persisting/reading BLOBS using JPA (the dreaded OutOfMemoryException that results when a byte[] is used for backing a BLOB and large BLOBS are created … say, from a file upload). Would love to hear your thoughts in dealing with this ;)

    Keep up the great work.

    Dave



    Tom Says:
    Posted at: April 4, 2009 at 5:29 pm

    Pretty good series of articles !
    Thanks a lot for your hints and tips.



    Dave Says:
    Posted at: April 4, 2009 at 6:21 pm

    @Vincent

    “…In case of JPA 2.0 or SessionFactory you could use Criteria for this, but that would leak your implementation details to the client code”.

    Sure, but in the interest of “scaling” well, does not the use of Specifications mean that you have to ship all your objects over the wire from the database in order to apply the Specification? At least with the Criteria API, you can let the database doing the selection for you (an operation it’s quite optimized at performing). Sure, for small result sets, using Specifications won’t impact performance at all. But what about for very large result sets?



    Tech Per Says:
    Posted at: April 4, 2009 at 8:13 pm

    Great blog entry!

    I was wondering: Do you have any advice or thoughts on how to name or design query methods to support eager loading for different usage scenarios?

    Say, I have a findOrdersSubmittedSince(…) method. And say an Order has OrderLines.

    In one use-case, the application only needs the Order instances. No need to load the OrderLines.

    On another use-case, the application needs to OrderLines too, hence I would like the find method to eager load the relation to OrderLines.

    But I don’t want to write two queries.

    And I don’t want methods like findOrdersWithOrderLinesLoadedSubmittedSince(…) or the like.

    Any thoughts?



    Stg Unholy Says:
    Posted at: April 5, 2009 at 3:28 pm

    This is really great articles! And I also struggling with situations, when sometimes You need just Order, and sometimes – Order with all items….The guidelines are really appreciated.



    Dave Says:
    Posted at: April 5, 2009 at 5:07 pm

    @Lars

    LOL…serves me right for posting *before* actually reading the chapter on Specifications in Evan’s DDD book. Turns out that implementing a Specification to return a Criteria object (or SQL string, if you like) to be executed by your domain Repository is perfectly valid, and gets around having to ship your objects across the wire to filter them. So Specs really do mesh well with Repositories (which is explicitly stated in the book). Apologies! (and apologies for calling you Vincent by mistake in the first post LOL).

    Dave



    Lars Says:
    Posted at: April 5, 2009 at 8:13 pm

    @Dave

    No need to apologise, I am glad you answered your own question :-) .



    Andrew Phillips Says:
    Posted at: April 6, 2009 at 12:18 pm

    @Lars, Dave: In case of JPA 2.0 or SessionFactory you could use Criteria for this, but that would leak your implementation details to the client code.

    I think that depends a little bit on whether you regard the use of a particular Criteria API as an “implementation detail”.

    If, for whatever reason, you do decide to add a “generic” find(Criteria) method to your DAO, you’ll need to use some kind of Criteria objects. Should you have to reinvent this particular wheel if a suitable implementation already exists?

    To be clear: this is only a question of perspective. If you decide to use the JPA Criteria in your DAO interface definition, you will still force clients to have a dependency on (that part of) JPA, which is something you may want/have to avoid.

    But I think it’s perfectly valid to interpret your interface’s definition of find as “the client can specify a set of filter criteria, and it is the job of the DAO implementation to interpret these and return the correct results”. And then, at least according to me, it’s not implementation leakage.

    In practice, of course, it may be difficult to use a certain Criteria API in any implementation other than the “native” one.
    Indeed, in previous projects I have ended up reinventing some of this wheel and writing my own Criteria API, together with a converter that converted “my” criteria to Hibernate criteria, for use in a Hibernate implementation.
    In this case, the reasons were, in fact, less related to enforced Hibernate dependencies. Instead, the key considerations were to

    • use only criteria objects that could be easily and cheaply serialized and constructed in other programming languages and
    • limit the expressiveness of the critiera API up front (i.e. on the client side), rather than returning CriteriaNotSupported-type errors later. We didn’t want to allow “A or B”, for instance, only “A and B”.


    Andrew Phillips Says:
    Posted at: April 6, 2009 at 12:23 pm

    @Tech: And I don’t want methods like findOrdersWithOrderLinesLoadedSubmittedSince(…) or the like. Any thoughts?

    When we were last faced with this problem, we also decided against findOrdersWithThisAndNotThat-type methods. In fact, we regarded them as violations of the DAO pattern (@Vincent: I’m curious as to what your thoughts on this are).

    In our opinion, a DAO should be tailored to retrieve the information that the application needs, with different methods for different needs. But from a domain model perspective, findOrdersWithThisAndThat and findOrdersWithThisButNotThat return the same information: a collection of Orders meeting some criteria.

    The WithThis… bit thus does not identify a different business need, it is simply a “hint” that only a certain part of the returned object graph is required, and that the rest may be ignored. The usual assumption being that this will lead to a performance improvement.

    But assume that, for some specific implementation, findWithThisButNotThat is actually slower/more memory intensive/more insert favourite performance metric here than findWithThisAndThat. Would it ever be called?

    Our approach was to (attempt to) model what we felt the WithThisAndThat actually represents: a suggestion to the implementation that only certain properties are required, and others may be ignored if this is likely to improve performance. We called it a FetchModel and allowed the user to specify FetchTypes (very similar to Hibernate’s FetchModels) for properties.

    For those DAO methods for which this was relevant, we then had an overloaded method (let’s defer the discussion about the evils of overloading for a minute)

      /** Uses the default fetch model */
      Collection findOrdersSubmittedSince(Date date);
    
      Collection findOrdersSubmittedSince(Date date, FetchModel fetchModel);
    

    where, in the case of your example, you would specify something like

      FetchModel noOrderLinesFetchModel = new FetchModel(Order.class);
      noOrderLinesFetchModel.setFetchType("orderLines", FetchType.NONE);
    

    It’s then down to the implementation to interpret the fetch model, if desired.

    Writing the code to actually implement a fetch model specification for a specific ORM framework is non-trivial, but if done with a bit of thought it can easily be reused.



    Vincent Partington Says:
    Posted at: April 6, 2009 at 7:03 pm

    @Lars: I don’t really have much to add on the Criteria thing after the comments by Dave and Andrew. :-) I guess it depends on what you use your DAO’s for, how flexible you want them to be.

    In the app we’re building we know up front the kind of queries we want to do (no search forms), so having findByXXX methods make sense. They are lot more expressive than having the client build some kind of specification object. Be it JPA Criteria or your own class.

    On the other hand if your app needs to support all kinds of ad hoc queries, such a mechanism makes sense.



    Vincent Partington Says:
    Posted at: April 6, 2009 at 7:12 pm

    @Tech, Andrew: I think Andrew’s suggestion seem pretty solid. I can see why having findOrdersWithOrderLinesLoadedSubmittedSince(…) methods would seem to violate the DAO pattern, but since I am not that much of a purist, I am not that much against them. ;-)

    I think I actually prefer them over having an extra (defaulted) argument that specifies the fetch strategy. That smells too much like the Flag Argument I’ve learned to abhor since reading Clean Code and Implementation Patterns.

    In fact since reading those books I’ve moved towards writing more shorter focused methods with descriptive (and therefore somtimes long) names instead of writing “clever” methods that can do all kinds of stuff when passed the right arguments. I guess that is why I’m not too enthusiastic about Lars’ criteria/specification suggestion.



    Tech Per Says:
    Posted at: April 6, 2009 at 7:47 pm

    Thanks for the viewpoints on methods for selecting for a use case. The FetchModel is interesting.



    JPA Implementation Patterns « Fernando Franzini Java Blog Says:
    Posted at: July 16, 2009 at 1:13 pm

    [...] Retrieving entities [...]



    Peter Kovacs Says:
    Posted at: August 8, 2009 at 2:40 pm

    @Dave: “implementing a Specification to return a Criteria object”

    But this wouldn’t be Specifiation pattern any more, would it be? Based on the article referenced by Lars, in the center of the Specification pattern there is an object which decides whether a domain object satisfies some condition(s) or not. In what you suggest, the decision is made outside the Specification, so I am not sure if this is still the same pattern. (I assume that by “Criteria object”, you mean a QueryDefinition object.)



    JPA Implementation Patterns | Upthrust Says:
    Posted at: January 30, 2010 at 12:29 pm

    [...] Retrieving Entities [...]



Leave a Reply

Click here to cancel reply.

Deployment automation for Java application running on Websphere, WebLogic and JBoss

Archives

  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009

Xebia Sites

  • Xebia Corporate
  • Xebia France
  • Xebia India

Categories

  • Java (279)
  • Agile (109)
  • General (50)
  • Testing (42)
  • Performance (42)
  • Hibernate (36)
  • Scrum (33)
  • Podcast (31)
  • Architecture (31)
  • Spring (28)
  • SOA (24)
  • Maven (22)
  • Project Management (22)
  • Flex (17)
  • JPA (17)
    • JPA implementation patterns (13)
  • Eclipse (15)
  • Quality Assurance (14)
  • Middleware (19)
  • Frameworks (13)

Tag Cloud

    Poppendieck Scrum Xebia Maven Functional Programming Spring Testing Grails Seam Lean Ajax Hibernate IntelliJ fitnesse qcon Architecture Performance product owner Agile Semantic Web Groovy Scala SOA esb JavaOne Agile Awareness Workshop Java XML Closures Introduction to Agile
medicin depression buy phentermine without a perscription aricept generic hair loss help how do you prevent bone loss urinary tract infection symptoms viagra sex domination cialis viagra cures for throat infection buy sumycin acne care new medication for cancer treatment help for sleeping problems on-line pharmacies cure snoring medications to help clot blood what is aspirin buy zestoretic bronchitis vs pneumonia back pain muscle acne face medication muscle women pain behind knee fat blocker man health arthritis natural cure woman health women insomnia cheap phentermine online cats and irritable bowel syndrome buy cialis generic online nutritional diet for osteoporosis abnormal blood clots treatments for hair loss what is zyprexa dental whitening products impotence herbs drugs for diabetes allergy prevention buy canada levitra Mentax adhd in children hair loss in woman medicines for blood clot online imitrex viagra buy free dog products clindamycin drug how to stop hair loss chloramphenicol discount drug viagra what valium does permanent hair loss heart failure medicine avapro 150mg ordering viagra online food allergies order viagra online online viagra prescription carisoprodol mg improve your skin discount erectile dysfunction medication buy xanax online buy order viagra scabies teatments information allegra vitamine b1 diazepam breast cancer support free stop smoking cipro side effects ultram cheapest treatment attention deficit disorder discount vitamins supplements how to get viagra online synthroid buy cheapest cialis zyrtec online how to clear acne preventive osteoporosis immune stimulants what is hoodia On Line Viagra getting over the pain diflucan dosage health asthma online stores hair loss products blood clot drugs colon parasites hair loss products discount medicine pravastatin buy griseofulvin tablets order indomethacin dog health products how to take a beta-blocker diazapan is valium treating cold sores chronic pain drug what is osteoporosis stress drug tooth whitening lowering cholesterol naturally legality of buying cialis online order levitra treatment for insomnia cheapest cialis index depakote overdose alprazolam condom sales treatment of yeast infection xanax sales taking viagra after cialis how to control pain new birth control chest pain health prozac prescription blood clots viagra in mexico chlamydia pill cancer drugs cold flu drugs how do i order viagra online super viagra acyclovir medicine benadryl dosage erythromycin pregnancy buy contoured condom chronic muscle pain pet health dogs treatment attention deficit disorder dental teeth whitening asthma medicine free prescription drugs herpes drug diabetes treatment buy tooth whitening gel cheap fast valium generic levitra buy cheapest viagra online lopressor drug pharmacy drug prices ultram dosing treatments for bipolar disorder neurontin withdrawal parasite medication chlamydia tips for increasing breast size ways to enhance breast what is valium used for metformin tablet order birth control hair loss for men how does xanax work treatment hepatitis c rythmol cheap acai antioxidants nexium generic blood pressure pills levitra online no prescription Levitra Online medications on line motion sickness drugs bactrim online order roxithromycin nicotine where can i order viagra immune supplements buy erexin v bph prostate allopurinol xanax for depression drug new smoking stop cheap impotence drug generic cialis delivery new treatment for depression antibiotics for cat viagra china alternative medicine cholesterol viagra dose anxiety disorder treatment severe muscle pain treatment of cancer calcium carbonate penis enlargement without pill valium maximum dosage reasons for high blood pressure energy product breast enlargement info cheap effexor building your body wrinkle cream aricept dosage alpha blocker increasing female sex drive valium depression new pain meds no rx xanax drug trileptal mg imitrex avapro 150mg medicine drugs contraception female claritin pill medication for acne med orders buy viagra internet levitra effect treatment for blood clots order sominex buy creatine buy precose cheap viagra overnight lopressor drug body building info health drugs general health and medical what is diazepam eye infections in dogs online prescription pills diclofenac tablet new medication anxiety buy citalopram medication male enhancement enhancement fat blocker medicine for throat infection order cardizem about soma health remedies for dogs generic xanax cheap zyrtec for depression medicine viagra sex domination buy acne skin care product hypnosis help study cure vaginal yeast infection weight loss supplement program muscle pain in leg how to increase erection buy viagra what is cla augmentin doses gaining muscle mass health med online heart rate treatments lopressor drug dog ear canal phentermine without prescription viagra order online weight loss glipizide diabetes astelin generic fat blocker buy gel tooth whitening cheap wellbutrin online weight loss program buy antiox anti-biotics acne skin treatmen tramadole vpxl pill drugs affecting levitra immune system support augmentin hypothyroidism medication buy erexin v uy prescription medication without a prescription buy discount order osteo arthritis online buy pilocarpine cheapest place to buy phentermine parasite treatment impotence help body fat loss viagra herb alternative constipation supplements treatment dementia adhd and medications muscle spasm relief viagra online cheap relieve upper back pain stop hair loss discount viagra online menstrual cycle problems antifungal shampoo side effects ativan gabapentin medication where can i buy viagra diazepam buy soma online clonidine dosage viagra gel top hair loss fast antibiotics cure chlamydia skin fungal infections drug zofran give up smoking alternative medicine cholesterol sleeping help best online viagra scams prednisone 10mg viagra sex domination lotensin easy weight loss pain meds without prescription over the counter drugs new high blood pressure medic generic compazine cetirizine drug order phentermine best fat blockers woman enhancement supplement drug zofran buy precose new drug treatment for cancer how to increase fertility viagra in australia benadryl dosing buy alcoholism medications order l arginine buy diazepam generic for ativan ativan prescription drugs weight loss treatment for chest pain woman health where can i buy phentermine online skin fungal infection give up smoking viagra on line hoodia information how does osteoporosis occur buy viagra online buy alcoholism medications depakote overdose klonopin pill tetracycline capsules what is high blood pressure bladder control for dogs generic for lipitor glucophage online pharmacy gabapentin dosage treating yeast infections dog health info cymbalta anxiety cheap tramadol without prescription hydrea drugs used for cancer cure for high blood pressure alcohol and valium relief from constipation liver infection treatment cialis soft zantac medication help sleep problems all natural antibiotics order medication without prescription sleep problems free hypnotherapy gaining muscle mass cheap viagra order online natural help for pain how to buy viagra drug price celebrex information otc diuretic levitra 10 mg buy medicine online pets products relief foot pain cialis without prescription med care cheapest generic cialis rapid hair loss pain medications generic side effects meds without prescriptions cat anxiety buy simplicef natural cure arthritis effects of high blood pressure lowest price generic viagra how to get birth control new breast cancer drug buy topamax blood pressure meds when are beta blockers prescribed how to get pain meds order fosamax online viagra name order viagra viagra cialis cat's eye health how to relieve lower back pain treating ear infections diazapan is valium online pain doctors high blood pressure in elderly medication to stop smoking wellbutrin dosages diabetes blood sugar levels weight loss diet pill side effects of prescribed pain pills drug list high blood pressure buy cialis online in usa ultram cost how to help osteoporosis how to use clomid discount brand viagra wellbutrin cymbalta buy pills without a prescription buy pain medicine online tab tramadol depression symptoms treatment how levitra work hypertension medications beta blockers prevent premature ejaculation xanax interactions with other medicines purchase medicine on line does alli work xenical mexico prescriptions buy sumycin uy prescription medication without a prescription ambien cost methocarbamol effects cheap beta blockers cats bladder reduce cholesterol naturally metformin tablet scabies medicine breast enhancer pills body building over 50 order viagra cheap zestril medication how to buy prescription medications online pharma kamagra drugs depression ear infection symptoms big muscle controlling blood pressure pain meds and pregnancy buy diazepam without prescription skin allergies antibiotic zoloft buy weight loss nutrition program Buy Cialis breast increase meds without prescriptions blood clots medical edema treatment for flu best hangover remedy diabetes drugs