DZone
Java Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Java Zone > JPA Implementation Patterns: Retrieving Entities

JPA Implementation Patterns: Retrieving Entities

Vincent Partington user avatar by
Vincent Partington
·
Jul. 29, 09 · Java Zone · Interview
Like (0)
Save
Tweet
36.45K Views

Join the DZone community and get the full member experience.

Join For Free

last time i talked about how to save an entity . and once we've saved an entity we'd also like to retrieve it. compared to 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.

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.

from http://blog.xebia.com

Database Implementation

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Creating a Spring Boot Project With Eclipse and Maven
  • Functional vs. Non-Functional Requirements: The Full Guide, Definitions, and Technical Examples
  • A Complete Guide About Scaled Agile Framework (SAFe)?
  • Cypress: The Future of Test Automation! Advantages and Disadvantages

Comments

Java Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo