{"id":20250,"date":"2014-01-07T19:00:32","date_gmt":"2014-01-07T17:00:32","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=20250"},"modified":"2014-01-07T08:32:03","modified_gmt":"2014-01-07T06:32:03","slug":"java-using-the-specification-pattern-with-jpa","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html","title":{"rendered":"Java: Using the specification pattern with JPA"},"content":{"rendered":"<p>This article is an introduction to using the specification pattern in Java. We also will see how we can combine classic specifications with JPA Criteria queries to retrieve objects from a relational database.<\/p>\n<p>Within this post we will use the following Poll class as an example entity for creating specifications. It represents a poll that has a start and end date. In the time between those two dates users can vote among different choices. A poll can also be locked by an administrator before the end date has been reached. In this case, a lock date will be set.<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n<pre class=\" brush:java\">@Entity\r\npublic\u00a0class\u00a0Poll\u00a0{\u00a0\r\n\r\n\u00a0\u00a0@Id\r\n\u00a0\u00a0@GeneratedValue\r\n\u00a0\u00a0private\u00a0long\u00a0id;\r\n\r\n\u00a0\u00a0private\u00a0DateTime\u00a0startDate;\u00a0\r\n\u00a0\u00a0private\u00a0DateTime\u00a0endDate;\r\n\u00a0\u00a0private\u00a0DateTime\u00a0lockDate;\r\n\r\n\u00a0\u00a0@OneToMany(cascade\u00a0=\u00a0CascadeType.ALL)\r\n\u00a0\u00a0private\u00a0List&lt;Vote&gt;\u00a0votes\u00a0=\u00a0new\u00a0ArrayList&lt;&gt;();\r\n\r\n}<\/pre>\n<p>For better readability I skipped getters, setters, JPA annotations for mapping Joda DateTime instances and fields that aren&#8217;t needed in this example (like the question being asked in the poll).<\/p>\n<p>Now assume we have two constraints we want to implement:<\/p>\n<ul>\n<li>A poll is <i>currently running<\/i> if it is not locked and if startDate &lt; now &lt; endDate<\/li>\n<li>A poll is <i>popular<\/i> if it contains more than 100 votes and is not locked<\/li>\n<\/ul>\n<p>We could start by adding appropriate methods to Poll like: poll.isCurrentlyRunning(). Alternatively we could use a service method like pollService.isCurrentlyRunning(poll). However, we also want to be able to query the database to get all currently running polls. So we might add a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Data_access_object\">DAO<\/a> or repository method like pollRepository.findAllCurrentlyRunningPolls().<\/p>\n<p>If we follow this way we implement the <i>isCurrentlyRunning<\/i> constraint two times in two different locations. Things become worse if we want to combine constraints. What if we want to query the database for a list of all popular polls that are currently running?<\/p>\n<p>This is where the specification pattern come in handy. When using the specification pattern we move business rules into extra classes called specifications.<\/p>\n<p>To get started with specifications we create a simple interface and an abstract class:<\/p>\n<pre class=\" brush:java\">public\u00a0interface\u00a0Specification&lt;T&gt;\u00a0{\u00a0\u00a0\r\n\u00a0\u00a0boolean\u00a0isSatisfiedBy(T\u00a0t);\u00a0\u00a0\r\n\u00a0\u00a0Predicate\u00a0toPredicate(Root&lt;T&gt;\u00a0root,\u00a0CriteriaBuilder\u00a0cb);\r\n\u00a0\u00a0Class&lt;T&gt;\u00a0getType();\r\n}<\/pre>\n<pre class=\" brush:java\">abstract\u00a0public\u00a0class\u00a0AbstractSpecification&lt;T&gt;\u00a0implements\u00a0Specification&lt;T&gt;\u00a0{\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0boolean\u00a0isSatisfiedBy(T\u00a0t)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0throw\u00a0new\u00a0NotImplementedException();\r\n\u00a0\u00a0}\u00a0\u00a0\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0Predicate\u00a0toPredicate(Root&lt;T&gt;\u00a0poll,\u00a0CriteriaBuilder\u00a0cb)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0throw\u00a0new\u00a0NotImplementedException();\r\n\u00a0\u00a0}\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0Class&lt;T&gt;\u00a0getType()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0ParameterizedType\u00a0type\u00a0=\u00a0(ParameterizedType)\u00a0this.getClass().getGenericSuperclass();\r\n\u00a0\u00a0\u00a0 return (Class&lt;T&gt;) type.getActualTypeArguments()[0];\r\n\u00a0 }\r\n}<\/pre>\n<p>Please ignore the AbstractSpecification&lt;T&gt; class with the mysterious getType() method for a moment (we come back to it later).<\/p>\n<p>The central part of a specification is the isSatisfiedBy() method, which is used to check if an object satisfies the specification. toPredicate() is an additional method we use in this example to return the constraint as javax.persistence.criteria.Predicate instance which can be used to query a database.<\/p>\n<p>For each constraint we create a new specification class that extends AbstractSpecification&lt;T&gt; and implements isSatisfiedBy() and toPredicate().<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>The specification implementation to check if a poll is currently running looks like this:<\/p>\n<pre class=\" brush:java\">public\u00a0class\u00a0IsCurrentlyRunning\u00a0extends\u00a0AbstractSpecification&lt;Poll&gt;\u00a0{\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0boolean\u00a0isSatisfiedBy(Poll\u00a0poll)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0return\u00a0poll.getStartDate().isBeforeNow()\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&amp;&amp;\u00a0poll.getEndDate().isAfterNow()\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&amp;&amp;\u00a0poll.getLockDate()\u00a0==\u00a0null;\r\n\u00a0\u00a0}\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0Predicate\u00a0toPredicate(Root&lt;Poll&gt;\u00a0poll,\u00a0CriteriaBuilder\u00a0cb)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0DateTime\u00a0now\u00a0=\u00a0new\u00a0DateTime();\r\n\u00a0\u00a0\u00a0\u00a0return\u00a0cb.and(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cb.lessThan(poll.get(Poll_.startDate),\u00a0now),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cb.greaterThan(poll.get(Poll_.endDate),\u00a0now),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cb.isNull(poll.get(Poll_.lockDate))\r\n\u00a0\u00a0\u00a0\u00a0);\r\n\u00a0\u00a0}\r\n}<\/pre>\n<p>Within isSatisfiedBy() we check if the passed object matches the constraint. In toPredicate() we construct a Predicate using JPA&#8217;s CriteriaBuilder. We will use the resulting Predicate instance later to build a CriteriaQuery for querying the database.<\/p>\n<p>The specification for checking if a poll is popular looks similar:<\/p>\n<pre class=\" brush:java\">public\u00a0class\u00a0IsPopular\u00a0extends\u00a0AbstractSpecification&lt;Poll&gt;\u00a0{\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0boolean\u00a0isSatisfiedBy(Poll\u00a0poll)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0return\u00a0poll.getLockDate()\u00a0==\u00a0null\u00a0&amp;&amp;\u00a0poll.getVotes().size()\u00a0&gt; 100;\r\n\u00a0\u00a0}\u00a0\u00a0\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0Predicate\u00a0toPredicate(Root&lt;Poll&gt;\u00a0poll,\u00a0CriteriaBuilder\u00a0cb)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0return\u00a0cb.and(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cb.isNull(poll.get(Poll_.lockDate)),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cb.greaterThan(cb.size(poll.get(Poll_.votes)),\u00a05)\r\n\u00a0\u00a0\u00a0\u00a0);\r\n\u00a0\u00a0}\r\n}<\/pre>\n<p>If we now want to test if a Poll instance matches one of these constraints we can use our newly created specifications:<\/p>\n<pre class=\" brush:java\">boolean isPopular = new\u00a0IsPopular().isSatisfiedBy(poll);\r\nboolean isCurrentlyRunning = new\u00a0IsCurrentlyRunning().isSatisfiedBy(poll);<\/pre>\n<p>For querying the database we need to extend our DAO \/ repository to support specifications. This can look like the following:<\/p>\n<pre class=\" brush:java\">public\u00a0class\u00a0PollRepository\u00a0{\r\n\r\n\u00a0\u00a0private\u00a0EntityManager\u00a0entityManager\u00a0=\u00a0...\r\n\r\n\u00a0\u00a0public\u00a0&lt;T&gt;\u00a0List&lt;T&gt;\u00a0findAllBySpecification(Specification&lt;T&gt;\u00a0specification)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0CriteriaBuilder\u00a0criteriaBuilder\u00a0=\u00a0entityManager.getCriteriaBuilder();\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/\u00a0use\u00a0specification.getType()\u00a0to\u00a0create\u00a0a\u00a0Root&lt;T&gt;\u00a0instance\r\n\u00a0\u00a0\u00a0\u00a0CriteriaQuery&lt;T&gt;\u00a0criteriaQuery\u00a0=\u00a0criteriaBuilder.createQuery(specification.getType());\r\n\u00a0\u00a0\u00a0\u00a0Root&lt;T&gt;\u00a0root\u00a0=\u00a0criteriaQuery.from(specification.getType());\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/\u00a0get\u00a0predicate\u00a0from\u00a0specification\r\n\u00a0\u00a0\u00a0\u00a0Predicate\u00a0predicate\u00a0=\u00a0specification.toPredicate(root,\u00a0criteriaBuilder);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ set predicate and execute query\r\n\u00a0\u00a0\u00a0\u00a0criteriaQuery.where(predicate);\r\n\u00a0\u00a0\u00a0\u00a0return\u00a0entityManager.createQuery(criteriaQuery).getResultList();\r\n\u00a0\u00a0}\r\n}<\/pre>\n<p>Here we finally use the getType() method implemented in AbstractSpecification&lt;T&gt; to create CriteriaQuery&lt;T&gt; and Root&lt;T&gt; instances. getType() returns the generic type of the AbstractSpecification&lt;T&gt; instance defined by the subclass. For IsPopular and IsCurrentlyRunning it returns the Poll class. Without getType() we would have to create the CriteriaQuery&lt;T&gt; and Root&lt;T&gt; instances inside toPredicate() of every specification we create. So it is just a small helper to reduce boiler plate code inside specifications. Feel free to replace this with your own implementation if you come up with better approaches.<\/p>\n<p>Now we can use our repository to query the database for polls that match a certain specification:<\/p>\n<pre class=\" brush:java\">List&lt;Poll&gt;\u00a0popularPolls\u00a0=\u00a0pollRepository.findAllBySpecification(new\u00a0IsPopular());\r\nList&lt;Poll&gt;\u00a0currentlyRunningPolls\u00a0=\u00a0pollRepository.findAllBySpecification(new\u00a0IsCurrentlyRunning());<\/pre>\n<p>At this point the specifications are the only components that contain the constraint definitions. We can use it to query the database or to check if an object fulfills the required rules.<\/p>\n<p>However one question remains: How do we combine two or more constraints? For example we would like to query the database for all popular polls that are still running.<\/p>\n<p>The answer to this is a variation of the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Composite_pattern\">composite design pattern<\/a> called composite specifications. Using a composite specification we can combine specifications in different ways.<\/p>\n<p>To query the database for all running and popular pools we need to combine the <i>isCurrentlyRunning<\/i> with the <i>isPopular<\/i> specification using the logical and operation. Let&#8217;s create another specification for this. We name it AndSpecification:<\/p>\n<pre class=\" brush:java\">public\u00a0class\u00a0AndSpecification&lt;T&gt;\u00a0extends\u00a0AbstractSpecification&lt;T&gt;\u00a0{\r\n\r\n\u00a0\u00a0private\u00a0Specification&lt;T&gt;\u00a0first;\r\n\u00a0\u00a0private\u00a0Specification&lt;T&gt;\u00a0second;\r\n\r\n\u00a0\u00a0public\u00a0AndSpecification(Specification&lt;T&gt;\u00a0first,\u00a0Specification&lt;T&gt;\u00a0second)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0this.first\u00a0=\u00a0first;\r\n\u00a0\u00a0\u00a0\u00a0this.second\u00a0=\u00a0second;\r\n\u00a0\u00a0}\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0boolean\u00a0isSatisfiedBy(T\u00a0t)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0return\u00a0first.isSatisfiedBy(t)\u00a0&amp;&amp;\u00a0second.isSatisfiedBy(t);\r\n\u00a0\u00a0}\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0Predicate\u00a0toPredicate(Root&lt;T&gt;\u00a0root,\u00a0CriteriaBuilder\u00a0cb)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0return\u00a0cb.and(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0first.toPredicate(root,\u00a0cb),\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0second.toPredicate(root,\u00a0cb)\r\n\u00a0\u00a0\u00a0\u00a0);\r\n\u00a0\u00a0}\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0Class&lt;T&gt;\u00a0getType()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0return\u00a0first.getType();\r\n\u00a0\u00a0}\r\n}<\/pre>\n<p>An AndSpecification is created out of two other specifications. In isSatisfiedBy() and toPredicate() we return the result of both specifications combined by a logical and operation.<\/p>\n<p>We can use our new specification like this:<\/p>\n<pre class=\" brush:java\">Specification&lt;Poll&gt;\u00a0popularAndRunning\u00a0=\u00a0new\u00a0AndSpecification&lt;&gt;(new\u00a0IsPopular(),\u00a0new\u00a0IsCurrentlyRunning());\r\nList&lt;Poll&gt;\u00a0polls\u00a0=\u00a0myRepository.findAllBySpecification(popularAndRunning);<\/pre>\n<p>To improve readability we can add an and() method to the Specification interface:<\/p>\n<pre class=\" brush:java\">public\u00a0interface\u00a0Specification&lt;T&gt;\u00a0{\r\n\r\n\u00a0\u00a0Specification&lt;T&gt;\u00a0and(Specification&lt;T&gt;\u00a0other);\r\n\r\n\u00a0\u00a0\/\/\u00a0other\u00a0methods\r\n}<\/pre>\n<p>and implement it within our abstract implementation:<\/p>\n<pre class=\" brush:java\">abstract\u00a0public\u00a0class\u00a0AbstractSpecification&lt;T&gt;\u00a0implements\u00a0Specification&lt;T&gt;\u00a0{\r\n\r\n\u00a0\u00a0@Override\r\n\u00a0\u00a0public\u00a0Specification&lt;T&gt;\u00a0and(Specification&lt;T&gt;\u00a0other)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0return\u00a0new\u00a0AndSpecification&lt;&gt;(this,\u00a0other);\r\n\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\/\/\u00a0other\u00a0methods\r\n}<\/pre>\n<p>Now we can chain multiple specification by using the and() method:<\/p>\n<pre class=\" brush:java\">Specification&lt;Poll&gt;\u00a0popularAndRunning\u00a0=\u00a0new\u00a0IsPopular().and(new\u00a0IsCurrentlyRunning());\r\nboolean\u00a0isPopularAndRunning\u00a0=\u00a0popularAndRunning.isSatisfiedBy(poll);\r\nList&lt;Poll&gt;\u00a0polls\u00a0=\u00a0myRepository.findAllBySpecification(popularAndRunning);<\/pre>\n<p>When needed we can easily extend this further with other composite specifications (for example OrSpecification or NotSpecification).<\/p>\n<h2>Conclusion<\/h2>\n<p>When using the specification pattern we move business rules in separate specification classes. These specification classes can be easily combined by using composite specifications. In general, specification improve reusability and maintainability. Additionally specifications can easily be unit tested. For more detailed information about the specification pattern I recommend <a href=\"http:\/\/martinfowler.com\/apsupp\/spec.pdf\">this article<\/a> by Eric Evans and Martin Fowler.<\/p>\n<ul>\n<li>You can find the source of this example project on <a href=\"https:\/\/github.com\/mscharhag\/JPA-Specifications-Example\">GitHub<\/a>.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/www.mscharhag.com\/2013\/12\/java-using-specification-pattern-with.html\">Java: Using the specification pattern with JPA<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Michael Scharhag at the <a href=\"http:\/\/www.mscharhag.com\/\">mscharhag, Programming and Stuff<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This article is an introduction to using the specification pattern in Java. We also will see how we can combine classic specifications with JPA Criteria queries to retrieve objects from a relational database. Within this post we will use the following Poll class as an example entity for creating specifications. It represents a poll that &hellip;<\/p>\n","protected":false},"author":514,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[33],"class_list":["post-20250","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-jpa"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Java: Using the specification pattern with JPA<\/title>\n<meta name=\"description\" content=\"This article is an introduction to using the specification pattern in Java. We also will see how we can combine classic specifications with JPA Criteria\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Java: Using the specification pattern with JPA\" \/>\n<meta property=\"og:description\" content=\"This article is an introduction to using the specification pattern in Java. We also will see how we can combine classic specifications with JPA Criteria\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2014-01-07T17:00:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Michael Scharhag\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/mscharhag\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michael Scharhag\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html\"},\"author\":{\"name\":\"Michael Scharhag\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/0f0f81e875d40e3f820392e0ffce65d1\"},\"headline\":\"Java: Using the specification pattern with JPA\",\"datePublished\":\"2014-01-07T17:00:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html\"},\"wordCount\":925,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"keywords\":[\"JPA\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html\",\"name\":\"Java: Using the specification pattern with JPA\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2014-01-07T17:00:32+00:00\",\"description\":\"This article is an introduction to using the specification pattern in Java. We also will see how we can combine classic specifications with JPA Criteria\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"java-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/java-using-the-specification-pattern-with-jpa.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Java: Using the specification pattern with JPA\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/0f0f81e875d40e3f820392e0ffce65d1\",\"name\":\"Michael Scharhag\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/52283459bfc820fb6a66704b3eccc771a1d8a63a0bdbbe1651bb5cb383a42148?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/52283459bfc820fb6a66704b3eccc771a1d8a63a0bdbbe1651bb5cb383a42148?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/52283459bfc820fb6a66704b3eccc771a1d8a63a0bdbbe1651bb5cb383a42148?s=96&d=mm&r=g\",\"caption\":\"Michael Scharhag\"},\"description\":\"Michael Scharhag is a Java Developer, Blogger and technology enthusiast. Particularly interested in Java related technologies including Java EE, Spring, Groovy and Grails.\",\"sameAs\":[\"http:\\\/\\\/www.mscharhag.com\\\/\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/mscharhag\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/michael-scharhag\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Java: Using the specification pattern with JPA","description":"This article is an introduction to using the specification pattern in Java. We also will see how we can combine classic specifications with JPA Criteria","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html","og_locale":"en_US","og_type":"article","og_title":"Java: Using the specification pattern with JPA","og_description":"This article is an introduction to using the specification pattern in Java. We also will see how we can combine classic specifications with JPA Criteria","og_url":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2014-01-07T17:00:32+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","type":"image\/jpeg"}],"author":"Michael Scharhag","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/mscharhag","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Michael Scharhag","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html"},"author":{"name":"Michael Scharhag","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/0f0f81e875d40e3f820392e0ffce65d1"},"headline":"Java: Using the specification pattern with JPA","datePublished":"2014-01-07T17:00:32+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html"},"wordCount":925,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","keywords":["JPA"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html","url":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html","name":"Java: Using the specification pattern with JPA","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2014-01-07T17:00:32+00:00","description":"This article is an introduction to using the specification pattern in Java. We also will see how we can combine classic specifications with JPA Criteria","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","width":150,"height":150,"caption":"java-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/java-using-the-specification-pattern-with-jpa.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Java: Using the specification pattern with JPA"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/0f0f81e875d40e3f820392e0ffce65d1","name":"Michael Scharhag","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/52283459bfc820fb6a66704b3eccc771a1d8a63a0bdbbe1651bb5cb383a42148?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/52283459bfc820fb6a66704b3eccc771a1d8a63a0bdbbe1651bb5cb383a42148?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/52283459bfc820fb6a66704b3eccc771a1d8a63a0bdbbe1651bb5cb383a42148?s=96&d=mm&r=g","caption":"Michael Scharhag"},"description":"Michael Scharhag is a Java Developer, Blogger and technology enthusiast. Particularly interested in Java related technologies including Java EE, Spring, Groovy and Grails.","sameAs":["http:\/\/www.mscharhag.com\/","https:\/\/x.com\/https:\/\/twitter.com\/mscharhag"],"url":"https:\/\/www.javacodegeeks.com\/author\/michael-scharhag"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/20250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/514"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=20250"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/20250\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=20250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=20250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=20250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}