DZone
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
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Data Engineering
  3. Databases
  4. JPA Implementation Patterns: Retrieving Entities

JPA Implementation Patterns: Retrieving Entities

Vincent Partington user avatar by
Vincent Partington
·
Jul. 29, 09 · Interview
Like (0)
Save
Tweet
Share
36.71K 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

  • How To Create and Edit Excel XLSX Documents in Java
  • Mr. Over, the Engineer [Comic]
  • Microservices Discovery With Eureka
  • Express Hibernate Queries as Type-Safe Java Streams

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • 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: