{"id":37020012,"url":"https://github.com/jaxio/jpa-query-by-example","last_synced_at":"2026-01-14T02:15:00.330Z","repository":{"id":5653930,"uuid":"6862957","full_name":"jaxio/jpa-query-by-example","owner":"jaxio","description":"The JPA Query by Example framework is used by projects generated by Celerio.","archived":false,"fork":false,"pushed_at":"2022-11-24T06:29:36.000Z","size":264,"stargazers_count":45,"open_issues_count":5,"forks_count":21,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-07-25T15:12:23.143Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.jaxio.com/en/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaxio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-11-26T09:55:45.000Z","updated_at":"2024-12-02T07:18:12.000Z","dependencies_parsed_at":"2023-01-11T20:13:14.921Z","dependency_job_id":null,"html_url":"https://github.com/jaxio/jpa-query-by-example","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/jaxio/jpa-query-by-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaxio%2Fjpa-query-by-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaxio%2Fjpa-query-by-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaxio%2Fjpa-query-by-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaxio%2Fjpa-query-by-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaxio","download_url":"https://codeload.github.com/jaxio/jpa-query-by-example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaxio%2Fjpa-query-by-example/sbom","scorecard":{"id":508671,"data":{"date":"2025-08-11","repo":{"name":"github.com/jaxio/jpa-query-by-example","commit":"7ee8503a5823ae5504d31fbdac24e0c7bd608828"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T23:55:08.629Z","repository_id":5653930,"created_at":"2025-08-19T23:55:08.629Z","updated_at":"2025-08-19T23:55:08.629Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-14T02:14:59.895Z","updated_at":"2026-01-14T02:15:00.323Z","avatar_url":"https://github.com/jaxio.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"## JPA Query by Example framework\n\n[![Build Status](https://travis-ci.org/jaxio/jpa-query-by-example.svg?branch=master)](https://travis-ci.org/jaxio/jpa-query-by-example)\n\nQuery By Example for JPA is originally inspired from [Hibernate Example criterion](https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/querycriteria.html#querycriteria-examples\n). But since Hibernate's Example is not part of JPA 2, we have created our own API, using JPA 2 only.\n\n\n## How To Use QBE \n\nWe do not cover here QBE implementation details, instead we explain how to use the Query By Example API.\n\nJPA Query by Example is available on Maven central repository:\n\n```xml\n\u003cdependency\u003e\n\t\u003cgroupId\u003ecom.jaxio\u003c/groupId\u003e\n\t\u003cartifactId\u003ejpa-querybyexample\u003c/artifactId\u003e\n\t\u003cversion\u003e1.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### Resources\n\n* Take a look directly at the [QBE junit tests](https://github.com/jaxio/jpa-query-by-example/blob/master/src/test/java/demo), they are almost self-explanatory.\n* Use Celerio to generate an advanced CRUD application that leverages this QBE API. See [Celerio](http://www.jaxio.com/documentation/celerio/installation.html)\n* [Watch a demo of an application generated by Celerio](https://www.facebook.com/video/video.php?v=524162864265905\u0026notif_t=video_processed)\n \n\n### Simple Query By Example\n\nIn its simplest form, Query By Example allows you to construct a query from a given entity instance.\n\nLet's assume we have an [Account entity](https://github.com/jaxio/jpa-query-by-example/blob/master/src/test/java/demo/Account.java) \nhaving a `lastName` property and that we want to query all accounts whose last name matches 'Jagger'.\n\nUsing QBE, constructing the query is as simple as setting the lastName...:\n\n```java\nAccount example = new Account();\nexample.setLastName(\"Jagger\");\nList\u003cAccount\u003e result = accountRepository.find(example);\n```\n\nAt the SQL level, the resulting query looks like this:\n\n```sql\nselect\n    -- skip other fields for clarity\n    account0_.LAST_NAME as LAST9_3_,\nfrom\n    Account account0_ \nwhere\n    account0_.LAST_NAME=?\n```\n\nThe [AccountRepository](https://github.com/jaxio/jpa-query-by-example/blob/master/src/test/java/demo/AccountRepository.java)\nextends a [GenericRepository](https://github.com/jaxio/jpa-query-by-example/blob/master/src/main/java/com/jaxio/jpa/querybyexample/GenericRepository.java)\n\n#### Case sensitivity, order by\n\nThe first query above involves a String. Let's change it to make it case insensitive.\n\nOur `Account` entity does not carry case sensitivity meta information. For this reason, we require some extra parameters \nfor case sensitivity, but also ordering, etc.\nThe number of parameters can grow quickly, so we have grouped them in the\n[SearchParameters](https://github.com/jaxio/jpa-query-by-example/blob/master/src/main/java/com/jaxio/jpa/querybyexample/SearchParameters.java) class \nwhich can be passed as a parameter to the accountRepository's methods.\n\nLet's make the first query above `case insensitive` and let's add an `ORDER BY`.\n\n```java\nAccount example = new Account();\nexample.setLastName(\"Jagger\"); \nSearchParameters sp = new SearchParameters().caseSensitive().orderBy(OrderByDirection.ASC, Account_.lastName);\nList\u003cAccount\u003e result = accountRepository.find(example, sp);\n```\n\nNote the usage of the \n[Account_](https://github.com/jaxio/jpa-query-by-example/blob/master/src/test/java/demo/Account_.java)* \nstatic metamodel, which helps you to keep your query related Java code strongly typed.\n\nAt the SQL level, the resulting FROM clause now looks like this:\n\n```sql\nfrom\n    ACCOUNT account0_ \nwhere\n    lower(account0_.LAST_NAME)=? \norder by\n    account0_.LAST_NAME asc\n```\n\n#### Pagination\n\nIn most web application we need to paginate the query results in order to save resources. In the query below, we retrieve only \nthe 3rd page (we assume a page lists 25 rows). The first result is the 50th element and we retrieve at most 25 elements.\n\n```java\nAccount example = new Account();\nexample.setLastName(\"Jagger\");\nSearchParameters sp = new SearchParameters().orderBy(OrderByDirection.ASC, Account_.lastName) //\n\t.first(50).maxResults(25);\nList\u003cAccount\u003e result = accountRepository.find(example, sp);\n```\n\nAt the SQL level, the resulting FROM clause now looks like this (we use H2 database):\n\n```sql\nfrom\n    ACCOUNT account0_ \nwhere\n    account0_.LAST_NAME=? \norder by\n    account0_.LAST_NAME asc limit ? offset ?\n```\n\n#### LIKE and String\n\nFor strings, you can globally control whether a `LIKE` should be used and where the `%` wildcard should be placed. For example, adding :\n\n```java\nexample.setLastName(\"Jag\");\nSearchParameters sp = new SearchParameters().startingLike();\n```\n\nto our example above would result in  \n\n```sql\naccount0_.LAST_NAME LIKE 'Jag%'\n```\n\n#### Multiple criteria\n\nUntil now, we have worked only with one property, lastName, but we can set other properties, for example:\n\n```java\nAccount example = new Account();\nexample.setLastName(\"Jag\");\nexample.setBirthDate(new Date());\nSearchParameters sp = new SearchParameters().orderBy(OrderByDirection.ASC, Account_.lastName).startingLike();\nList\u003cAccount\u003e result = accountRepository.find(example, sp);\n```\n\nBy default, the FROM clause uses a `AND` predicate. \n\n```sql\nfrom\n    ACCOUNT account0_ \nwhere\n    account0_.BIRTH_DATE=? \n    and (\n        account0_.LAST_NAME like ?\n    ) \norder by\n    account0_.LAST_NAME asc\n```\n\nTo use instead `OR`, use the `.orMode()`, as follow:\n\n```java\nSearchParameters sp = new SearchParameters().orMode().orderBy(OrderByDirection.ASC, Account_.lastName).startingLike();\n```\n\nAnd this time we get:\n\n```sql\nwhere\n    account0_.LAST_NAME like ? \n    or account0_.BIRTH_DATE=? \norder by\n    account0_.LAST_NAME asc\n```\n\n#### Is that all ?\n\nNot really, we have just scratched the surface. For the moment, we have covered only rather simple queries.\nWhile simplicity is key, it is often not sufficient. What about date or number range queries ?  What about associated entities ? etc.\n\n### Beyond Query By Example\n\n#### Mixing Query by Example and Range Query.\n\nNow, let's imagine that you also want to restrict the query above to all accounts having their date of birth between 1940 and 1945 included.\nOf course, the entity does not have the appropriate property (from \u0026 to). \nFor this reason, we introduce an additional \n[Range](https://github.com/jaxio/jpa-query-by-example/blob/master/src/main/java/com/jaxio/jpa/querybyexample/Range.java) \nparameter.\n\nHere is an example:\n\n```java\nAccount example = new Account();\nexample.setLastName(\"Jagger\");\n\nCalendar from = Calendar.getInstance();\nfrom.set(1940, 0, 1);\n\nCalendar to = Calendar.getInstance();\nto.set(1945, 11, 31);\n\nRange\u003cAccount, Date\u003e birthDateRange = Range.newRange(Account_.birthDate);\nbirthDateRange.from(from.getTime()).to(to.getTime());\n\nSearchParameters sp = new SearchParameters().range(birthDateRange);\nList\u003cAccount\u003e result = accountRepository.find(example, sp);\n```\n\nNote that you can add ranges of any type: Integer, Long, LocalDate (joda time), BigDecimal, etc...\n\nThis codes leads in fine to following `FROM` clause:\n\n```sql\nfrom\n    ACCOUNT account0_ \nwhere\n    (\n        account0_.BIRTH_DATE between ? and ?\n    ) \n    and account0_.LAST_NAME=?\n```\n\nHere is a variation of the same example (depends on need, taste and color :-): \n\n```java\nDateFormat dateFormat = new SimpleDateFormat(\"yyyy-MM-dd\");\nDate from = dateFormat.parse(\"1920-12-01\");\nDate to = dateFormat.parse(\"1974-12-01\");\n\nSearchParameters sp = new SearchParameters().range(from, to, Account_.birthDate);\nList\u003cAccount\u003e accountList = accountRepository.find(sp);\n```\n\n#### Query all string properties in a OR clause\n\nTo find all entities having at least one of their String property matching a given value, use the `searchPattern` method.\n\nHere is an example: \n\n```java    \nSearchParameters sp = new SearchParameters().searchMode(SearchMode.STARTING_LIKE).searchPattern(\"Jag\");\nList\u003cAccount\u003e result = accountRepository.find(sp);\n```\n\nThe FROM clause now includes all string columns:\n\n```sql\nfrom\n    ACCOUNT account0_ \nwhere\n    or account0_.LAST_NAME like ? \n    or account0_.USERNAME like ? \n```\n\n#### Property Selector\n\nIn order to construct a `OR` clause for a given property we use the `PropertySelector` class.\n\nHere is an example:\n\n```java    \nPropertySelector\u003cAccount, String\u003e lastNameSelector = PropertySelector.newPropertySelector(Account_.lastName);\nlastNameSelector.setSelected(Arrays.asList(\"Jagger\", \"Richards\", \"Jones\", \"Watts\", \"taylor\", \"Wyman\", \"Wood\"));\n\nSearchParameters sp = new SearchParameters().property(lastNameSelector);\n\nList\u003cAccount\u003e result = accountRepository.find(sp);\n```\n\nHere is the corresponding FROM clause: \n\n```sql\n\tfrom\n\t    ACCOUNT account0_ \n\twhere\n\t    account0_.LAST_NAME='Jagger'\n\t    or account0_.LAST_NAME='Richards'\n\t    or account0_.LAST_NAME='Jones'\n\t    or account0_.LAST_NAME='Watts'\n\t    or account0_.LAST_NAME='Taylor'\n\t    or account0_.LAST_NAME='Wyman'\n\t    or account0_.LAST_NAME='Wood'\n```\n\nNote that if you use JSF2 with PrimeFaces, you can directly pass a `PropertySelector` to a multiple autoComplete component's value property.\nThis way, the autoComplete component fills the PropertySelector. Here is how:\n\n```xml\n\u003cp:autoComplete ... multiple=\"true\" value=\"#{accountSearchForm.lastNameSelector.selected}\" ... /\u003e\n```\n\nHere is a snapshot:\n\n![property selector](https://github.com/jaxio/jpa-query-by-example/blob/master/src/img/property-selector.png)\n\nPrimeFaces uses the `setSelected(List\u003cAccount\u003e selection)` method to fill the lastNameSelector.\n\n#### Mix it all\n\nRemember, you can mix all the example we have seen so far.\nYou can have in a single query having multiple ranges, multiple property selector, multiple properties set on the example entity, etc.\n\nThis gives you great power ;-)\n\n#### Query By Example on association\n\nThe `Account` entity has a `@ManyToOne` association with the `Address` entity.\n\nHere is how we can retrieve all accounts pointing to an Address having its `city` property set to \"Paris\":\n\n```java    \nAccount example = new Account();\nexample.setHomeAddress(new Address());\nexample.getHomeAddress().setCity(\"Paris\");\nList\u003cAccount\u003e result = accountRepository.find(example);\nAssert.assertThat(result.size(), is(2));\n```\n\nThe FROM clause uses a JOIN:\n\n```sql\nfrom\n    ACCOUNT account0_ cross \njoin\n    ADDRESS address1_ \nwhere\n    account0_.ADDRESS_ID=address1_.ID \n    and address1_.CITY='Paris'\n```\n\nEnjoy!\n\n\n## License\n\nThe JPA Query By Example Framework is released under version 2.0 of the [Apache License][].\n\n[Apache License]: http://www.apache.org/licenses/LICENSE-2.0\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaxio%2Fjpa-query-by-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaxio%2Fjpa-query-by-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaxio%2Fjpa-query-by-example/lists"}