{"id":51324199,"url":"https://github.com/martiner/objectify-spring-boot-starter","last_synced_at":"2026-07-01T16:32:44.659Z","repository":{"id":362157608,"uuid":"1255431318","full_name":"martiner/objectify-spring-boot-starter","owner":"martiner","description":"Spring Boot auto-configuration for Objectify (Cloud Datastore).","archived":false,"fork":false,"pushed_at":"2026-06-10T19:17:36.000Z","size":42,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-10T21:09:19.886Z","etag":null,"topics":["appengine-java","objectify","spring","spring-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martiner.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-31T20:23:50.000Z","updated_at":"2026-06-10T19:17:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/martiner/objectify-spring-boot-starter","commit_stats":null,"previous_names":["martiner/objectify-spring-boot-starter"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/martiner/objectify-spring-boot-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martiner%2Fobjectify-spring-boot-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martiner%2Fobjectify-spring-boot-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martiner%2Fobjectify-spring-boot-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martiner%2Fobjectify-spring-boot-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martiner","download_url":"https://codeload.github.com/martiner/objectify-spring-boot-starter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martiner%2Fobjectify-spring-boot-starter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35015053,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-01T02:00:05.325Z","response_time":130,"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":["appengine-java","objectify","spring","spring-boot"],"created_at":"2026-07-01T16:32:44.577Z","updated_at":"2026-07-01T16:32:44.653Z","avatar_url":"https://github.com/martiner.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# objectify-spring-boot-starter\n\nSpring Boot auto-configuration for [Objectify](https://github.com/objectify/objectify) (Cloud Datastore).\n\nTargets Spring Boot 4.x.\n\n## Usage\n\nAdd the dependency:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecz.geek\u003c/groupId\u003e\n    \u003cartifactId\u003eobjectify-spring-boot-starter\u003c/artifactId\u003e\n    \u003cversion\u003e0.2.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nThe starter auto-configures an `ObjectifyFactory` bean and registers a servlet filter that opens a per-request Objectify session. Both `factory.ofy()` (injected factory bean) and the static `ObjectifyService.ofy()` work — they share the same factory instance.\n\n## Configuration\n\n| Property | Default | Description |\n|---|---|---|\n| `objectify.port` | `-1` | Datastore emulator port. `-1` = production. |\n| `objectify.project` | `` | GCP project ID. For the emulator it is optional and defaults to `test` (the emulator does not match it against the client); in production the ambient GCP project is used. |\n| `objectify.filter-enabled` | `true` | Register the Objectify servlet filter. Set to `false` to disable it — useful when you want to manage sessions yourself (e.g. call `factory.begin()` around units of work, or register your own filter). |\n| `objectify.filter-order` | auto | Servlet filter order. When Spring Security is on the classpath this defaults to just before Spring Security's filter chain (`spring.security.filter.order - 1`); otherwise unordered. Set explicitly to override. |\n| `objectify.entity-scan-enabled` | `true` | Enable classpath scanning for `@Entity` classes. Set to `false` to rely solely on `ObjectifyEntityProvider` beans. |\n\n## Registering entities\n\nThere are three ways to register entities. They combine additively: programmatic providers (option 3) are always registered, and classpath scanning (option 1 *or* 2) adds to them.\n\n### Option 1 — Automatic classpath scan (zero config)\n\nBy default the starter scans the application's base package (determined by `@SpringBootApplication`) for classes annotated with `@com.googlecode.objectify.annotation.Entity`. If your entities live under the application package, you need to do nothing.\n\n### Option 2 — `@ObjectifyEntityScan` (custom packages)\n\nUse this when entities live outside the application's base package. The annotation **replaces** the default package scan — it does not add to it, so list every package that contains entities, including the application's own base package if needed:\n\n```java\n@ObjectifyEntityScan(basePackages = {\"com.example\", \"com.example.entities\"})\n@SpringBootApplication\npublic class MyApp { ... }\n```\n\nTo skip classpath scanning entirely (e.g. for faster startup) and rely solely on option 3, set `objectify.entity-scan-enabled=false`.\n\n### Option 3 — Programmatic provider\n\nRegister entity classes explicitly via an `ObjectifyEntityProvider` Spring bean:\n\n```java\n@Component\npublic class MyEntities implements ObjectifyEntityProvider {\n    @Override\n    public Collection\u003cClass\u003c?\u003e\u003e getEntities() {\n        return List.of(MyEntity.class, OtherEntity.class);\n    }\n}\n```\n\n\u003e **Note:** If you define your own `ObjectifyFactory` bean, the auto-configuration backs off entirely (including entity registration and `ObjectifyService.init`). Your bean takes full responsibility.\n\n\u003e **Note:** To replace the auto-configured filter while keeping the factory, define a `FilterRegistrationBean` bean named exactly **`objectifyFilter`**. A bean registered under any other name will not replace the auto-configured one — both would be active.\n\n\u003e **Warning (multi-context tests):** `ObjectifyService.init` is a global singleton. In a test suite that starts multiple Spring application contexts in the same JVM, whichever context was initialized last wins. Injecting `ObjectifyFactory` directly (rather than using the static `ObjectifyService.ofy()`) is the reliable approach in such scenarios.\n\n## Testing — `@ObjectifyTest` slice\n\n`@ObjectifyTest` is a test slice in the spirit of `@DataJpaTest`: it disables full\nauto-configuration and applies only `ObjectifyAutoConfiguration`, giving you a ready-to-use\n`ObjectifyFactory` bean (entities scanned, `ObjectifyService` initialized). Regular\n`@Component` / `@Service` / `@Controller` beans are **not** loaded, so the context stays\nsmall and your application's other configuration (security, mail, …) is not required.\n\nEntities are discovered automatically from the base package of your application's\n`@SpringBootConfiguration` — exactly like `@DataJpaTest` finds `@Entity` classes.\n\nThe slice support lives in the main artifact but its compile dependencies\n(`spring-boot-test`, `spring-test`, JUnit) are `optional`; you get them on the test\nclasspath via `spring-boot-starter-test`.\n\n```java\n@ObjectifyTest\nclass MyEntityRepositoryTest {\n\n    @Autowired\n    ObjectifyFactory factory;\n\n    @Test\n    void savesAndLoads() {\n        try (Closeable ignored = factory.begin()) {\n            Key\u003cMyEntity\u003e key = factory.ofy().save().entity(new MyEntity(\"a\")).now();\n            assertThat(factory.ofy().load().key(key).now()).isNotNull();\n        }\n    }\n}\n```\n\nIt works the same with Kotest (constructor injection via `SpringAutowireConstructorExtension`):\n\n```kotlin\n@ObjectifyTest\nclass MyEntityRepositoryIT(factory: ObjectifyFactory) : FreeSpec({\n    val repo = MyEntityRepository(factory)\n    \"loads by id\" {\n        factory.begin().use { /* ... repo.load(id) ... */ }\n    }\n})\n```\n\nPoint the test at the emulator with `objectify.port` (via the `properties` attribute or\nthe environment); `objectify.project` is optional and defaults to `test`.\n\nYour own repository/`@Service` beans are not in the slice by default. Pull in specific\nones when you need them injected:\n\n```java\n@ObjectifyTest(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = MyEntityRepository.class))\n```\n\nor with `@Import(MyEntityRepository.class)` — otherwise just instantiate them with the\ninjected factory.\n\n## Releasing\n\n```bash\n./mvnw release:prepare\n./mvnw release:perform\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartiner%2Fobjectify-spring-boot-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartiner%2Fobjectify-spring-boot-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartiner%2Fobjectify-spring-boot-starter/lists"}