{"id":17147940,"url":"https://github.com/lazaronixon/active-persistence","last_synced_at":"2025-04-13T11:40:21.864Z","repository":{"id":57728780,"uuid":"271923832","full_name":"lazaronixon/active-persistence","owner":"lazaronixon","description":"Active Persistence is a implementation of Active Record Query Interface for JPA that makes it easy and fun.","archived":false,"fork":false,"pushed_at":"2021-02-01T17:36:51.000Z","size":674,"stargazers_count":16,"open_issues_count":6,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-27T02:43:40.999Z","etag":null,"topics":["activerecord","jakartaee","java","java-api","java-orm","jpa","jpql","orm","orm-framework","query","query-builder","sql"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lazaronixon.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":"2020-06-13T02:05:47.000Z","updated_at":"2024-07-04T06:14:23.000Z","dependencies_parsed_at":"2022-09-09T09:31:03.561Z","dependency_job_id":null,"html_url":"https://github.com/lazaronixon/active-persistence","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazaronixon%2Factive-persistence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazaronixon%2Factive-persistence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazaronixon%2Factive-persistence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazaronixon%2Factive-persistence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lazaronixon","download_url":"https://codeload.github.com/lazaronixon/active-persistence/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248709197,"owners_count":21149146,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["activerecord","jakartaee","java","java-api","java-orm","jpa","jpql","orm","orm-framework","query","query-builder","sql"],"created_at":"2024-10-14T21:26:37.304Z","updated_at":"2025-04-13T11:40:21.821Z","avatar_url":"https://github.com/lazaronixon.png","language":"Java","readme":"## Getting Started\n\npom.xml\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.lazaronixon\u003c/groupId\u003e\n  \u003cartifactId\u003eactive-persistence\u003c/artifactId\u003e\n  \u003cversion\u003e0.0.31\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nmodels/User.java\n```java\n@Entity\npublic class User extends BaseIdentity {\n\n    private String name;\n\n    private String occupation;\n\n    private LocalDateTime createdAt;\n\n    private LocalDateTime updatedAt;\n\n    // Get/Set omitted by brevity\n}\n```\n\nrepositories/UserRepository.java\n```java\n@RequestScoped\npublic class UserRepository extends Base\u003cUser\u003e {\n\n}\n```\n\n## CRUD: Reading and Writing Data\n\n### Create\n```java\nUser user = new User();\nuser.name = \"David\";\nuser.occupation = \"Code Artist\";\n\nuserRepository.save(user);\n```\n\n### Read\n```java\n// return a collection with all users\nList\u003cUser\u003e users = userRepository.all();\n\n// return the first user\nUser user = userRepository.first();\n\n// return the first user named David\nUser david = userRepository.findBy(\"user.name = ?\", \"David\");\n\n// find all users named David who are Code Artists and sort by createdAt in reverse chronological order\nList\u003cUser\u003e users = userRepository.where(\"user.name = 'David' AND user.occupation = 'Code Artist'\").order(\"user.createdAt DESC\");\n```\n\n### Update\n```java\nUser user = userRepository.findBy(\"user.name = ?\", \"David\");\nuser.name = \"Dave\";\nuserRepository.save(user);\n//OR\nuserRepository.updateAll(\"user.maxLoginAttempts = 3, user.mustChangePassword = 'true'\");\n```\n\n### Delete\n```java\nUser user = userRepository.findBy(\"user.name = ?\", \"David\");\nuserRepository.destroy(user);\n//OR\nuserRepository.destroyBy(\"user.name = ?\", \"David\");\nuserRepository.destroyAll();\n```\n\n### Callbacks\n\n```java\npublic class ClientRepository extends Base\u003cClient\u003e {\n\n    @Override\n    public void beforeSave(Client client) {\n        // implementation here\n    }\n\n    @Override\n    public void afterSave(Client client) {\n        // implementation here\n    }\n\n    @Override\n    public void beforeCreate(Client client) {\n        // implementation here\n    }\n\n    @Override\n    public void afterCreate(Client client) {\n        // implementation here\n    }\n\n    @Override\n    public void beforeUpdate(Client client) {\n        // implementation here\n    }\n\n    @Override\n    public void afterUpdate(Client client) {\n        // implementation here\n    }\n\n    @Override\n    public void beforeDestroy(Client client) {\n        // implementation here\n    }\n\n    @Override\n    public void afterDestroy(Client client) {\n        // implementation here\n    }\n\n}\n```\n\n### TimeStamps\n```java\npublic class Post extends BaseIdentity {\n\n    private LocalDateTime createdAt;\n\n    private LocalDateTime updatedAt;\n\n    @Override\n    public void setCreatedAt(LocalDateTime createdAt) {\n        this.createdAt = createdAt;\n    }\n\n    @Override\n    public void setUpdatedAt(LocalDateTime updatedAt) {\n        this.updatedAt = updatedAt;\n    }\n}\n```\n\n## Retrieving Objects from the Database\n\n### Retrieving a Single Object\n```java\n// Find the client with primary key (id) 10.\nClient client = clientRepository.find(10);\n\n// The take method retrieves a record without any implicit ordering\nClient client = clientRepository.take();\nList\u003cClient\u003e clients = clientRepository.take(2);\n\n// The first method finds the first record ordered by primary key (default)\nClient client = clientRepository.first();\nClient client = clientRepository.order(\"client.firstName\").first();\nList\u003cClient\u003e clients = clientRepository.first(3);\n\n// The last method finds the last record ordered by primary key (default)\nClient client = clientRepository.last();\nClient client = clientRepository.order(\"client.firstName\").last();\nList\u003cClient\u003e clients = clientRepository.last(3);\n\n// The findBy method finds the first record matching some conditions\nClient client = clientRepository.findBy(\"client.firstName = ?\", \"Lifo\"); // #\u003cClient id: 1, firstName: \"Lifo\"\u003e\nClient client = clientRepository.findBy(\"client.firstName = ?\", \"Jon\");  // null\n\nClient client = clientRepository.findBy$(\"client.firstName = ?\", \"does not exist\"); // EntityNotFoundException\n```\n\n### Conditions\n```java\n//Ordinal Conditions\nclientRepository.where(\"client.ordersCount = ?\", 10);\nclientRepository.where(\"client.ordersCount = ? AND client.locked = ?\", 10, false);\n\n//Placeholder Conditions\nclientRepository.where(\"client.ordersCount = :count\", Map.of(\"count\", 10));\nclientRepository.where(\"client.ordersCount = :count AND client.locked = :locked\", Map.of(\"count\", 10, \"locked\", false));\n\n//SubQuery Conditions\nvar subquery = clientRepository.select(\"order.client.id\");\nclientRepository.where(\"client.id IN (?), subquery);\n```\n\n### Ordering\n```java\nclientRepository.order(\"client.createdAt\");\nclientRepository.order(\"client.createdAt DESC\");\nclientRepository.order(\"client.createdAt ASC\");\n```\n\n### Selecting Specific Fields\n```java\nList\u003cClient\u003e client = clientRepository.select(\"client.viewableBy\", \"client.locked\");\nList\u003cClient\u003e client = clientRepository.select(\"client.name\").distinct();\n```\n\n### Limit and Offset\n```java\nclientRepository.limit(5);\nclientRepository.limit(5).offset(30);\n```\n\n### Group\n```java\nList\u003cOrder\u003e orders = orderRepository.select(\"date(order.createdAt)\", \"sum(order.price)\").group(\"date(order.createdAt)\");\n```\n\n### Total of grouped items\n```java\nMap\u003cString, Long\u003e result = (Map) orderRepository.group(\"order.status\").count(); // =\u003e { 'awaiting_approval' =\u003e 7, 'paid' =\u003e 12 }\n```\n\n### Having\n```java\nList\u003cOrder\u003e orders = orderRepository.select(\"date(order.createdAt)\", \"sum(order.price)\").group(\"date(order.createdAt)\").having(\"sum(order.price) \u003e 100\");\n```\n\n## Overriding Conditions\n\n### Unscope\n```java\norderRepository.where(\"order.id \u003e 10\").limit(20).order(\"order.id asc\").unscope(ORDER);\n```\n\n### Only\n```java\norderRepository.where(\"order.id \u003e 10\").limit(20).order(\"order.id asc\").only(ORDER);\n```\n\n### Reselect\n```java\npostRepository.select(\"post.title\", \"post.body\").reselect(\"post.createdAt\");\n```\n\n### Reorder\n```java\npostRepository.order(\"post.title\").reorder(\"post.createdAt\");\n```\n\n### Rewhere\n```java\narticleRepository.where(\"article.trashed = true\").rewhere(\"article.trashed = false\");\n```\n\n## Null Relation\n```java\nstudentRepository.none(); // returns an empty Relation and fires where 1=0.\n```\n\n## Locking Records for Update\n```java\nClient client = clientRepository.lock().first();\n// OR\nClient client = clientRepository.lock(true).first();\n// OR\nClient client = clientRepository.lock(PESSIMISTIC_WRITE).first();\n```\n\n## Readonly Objects\n```java\nClient client = clientRepository.readonly().first();\nclient.visits = 1;\n\nclientRepository.save(); // ReadOnlyRecord Exception\n```\n\n## Joining Tables\n```java\nauthorRepository.joins(\"JOIN author.post post\");\n```\n\n## Eager Loading Associations (EclipseLink only)\n```java\nclientRepository.includes(\"client.address\").limit(10);\nclientRepository.eagerLoads(\"client.address\").limit(10);\n```\n\n## Scopes\n\n### Applying a default scope\n```java\npublic class ClientRepository extends Base\u003cClient\u003e {\n\n    @Override\n    public Relation\u003cClient\u003e defaultScope() {\n        return where(\"client.name = 'nixon'\");\n    }\n\n}\n\nclientRepository.all(); // SELECT client FROM Client client WHERE client.name = 'nixon'\nclientRepository.unscoped().all(); // SELECT client FROM Client client\n```\n\n### Merging of scopes\n```java\nuserRepository.merge(active());\n```\n\n### Removing All Scoping\n```java\nclientRepository.unscoped();\nclientRepository.where(\"client.published = false\").unscoped();\n```\n\n## Dynamic Finders\n```java\nClient client = clientRepository.findByExpression(\"Name\", \"Nixon\");\nClient client = clientRepository.findByExpression(\"NameAndLocked\", \"Nixon\", true);\n// OR\nClient client = clientRepository.findByExpression$(\"Name\", \"not found\"); // EntityNotFoundException\n```\n\n## Finding by SQL/JPQL\n```java\nList\u003cPost\u003e posts = postRepository.findBySql(\"SELECT id, title FROM Post WHERE id = 5\").getResultList();\nList\u003cPost\u003e posts = postRepository.findByJpql(\"SELECT p FROM Post p WHERE p.id = 5\").getResultList();\n// OR\nList posts = postRepository.getConnection().selectAll(\"SELECT id, title FROM Post WHERE id = 5\", QueryType.SQL).getResultList();\nList posts = postRepository.getConnection().selectAll(\"SELECT p FROM Post p WHERE p.id = 5\", QueryType.JPQL).getResultList();\n```\n\n## Existence of Objects\n```java\nboolean exists = studentRepository.exists(\"student.name = 'Lifo'\");\nboolean exists = studentRepository.where(\"student.name = 'Lifo'\").exists();\n```\n\n## Pluck\n```java\nList\u003cInteger\u003e ids = clientRepository.where(\"client.active = true\").pluck(\"client.id\"); //[1, 2, 3]\nList\u003cInteger\u003e ids = clientRepository.where(\"client.active = true\").ids; //[1, 2, 3]\n```\n\n## Calculations\n```java\nlong   count   = (long)   clientRepository.count();\nlong   count   = (long)   clientRepository.count(\"client.age\");\nint    minimum = (int)    clientRepository.minimum(\"client.age\");\nint    maximum = (int)    clientRepository.maximum(\"client.age\");\nlong   total   = (long)   clientRepository.sum(\"client.ordersCount\");\ndouble average = (double) clientRepository.average(\"client.ordersCount\");\n```\n\n## Recommended Environment\n* Java 9\n* JakartaEE 8\n* Payara Server\n\n## Testing\n* Install Payara Server \u003e= 5.201\n* Add Resources - ./asadmin add-resources path_to/payara-resources.xml\n\n## More info\n* https://github.com/lazaronixon/jsf-perfect-crud/tree/active-persistence\n* https://www.youtube.com/watch?v=Hw8iKrZQk4o\n* https://guides.rubyonrails.org/active_record_querying.html\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flazaronixon%2Factive-persistence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flazaronixon%2Factive-persistence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flazaronixon%2Factive-persistence/lists"}