{"id":22477478,"url":"https://github.com/orienteerbap/transponder","last_synced_at":"2026-04-02T14:56:05.502Z","repository":{"id":57739752,"uuid":"411853287","full_name":"OrienteerBAP/Transponder","owner":"OrienteerBAP","description":"Object Mapping Framework for NoSQL databases","archived":false,"fork":false,"pushed_at":"2024-02-15T08:28:25.000Z","size":235,"stargazers_count":19,"open_issues_count":9,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-14T11:03:27.223Z","etag":null,"topics":["arcadedb","hibernate","mongodb","neo4j","nosql","object-mapping","orientdb","orm-framework"],"latest_commit_sha":null,"homepage":"","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/OrienteerBAP.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}},"created_at":"2021-09-29T23:01:20.000Z","updated_at":"2025-01-09T08:45:54.000Z","dependencies_parsed_at":"2024-02-15T09:42:32.976Z","dependency_job_id":null,"html_url":"https://github.com/OrienteerBAP/Transponder","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/OrienteerBAP/Transponder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrienteerBAP%2FTransponder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrienteerBAP%2FTransponder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrienteerBAP%2FTransponder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrienteerBAP%2FTransponder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OrienteerBAP","download_url":"https://codeload.github.com/OrienteerBAP/Transponder/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrienteerBAP%2FTransponder/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259804839,"owners_count":22913901,"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":["arcadedb","hibernate","mongodb","neo4j","nosql","object-mapping","orientdb","orm-framework"],"created_at":"2024-12-06T14:11:17.510Z","updated_at":"2026-04-02T14:56:05.494Z","avatar_url":"https://github.com/OrienteerBAP.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Java CI](https://github.com/OrienteerBAP/Transponder/actions/workflows/maven.yml/badge.svg)](https://github.com/OrienteerBAP/Transponder/actions/workflows/maven.yml) [![Build Status](https://app.travis-ci.com/OrienteerBAP/Transponder.svg?branch=master)](https://app.travis-ci.com/OrienteerBAP/Transponder)\n\n![Transponder_Logo](https://user-images.githubusercontent.com/1199285/138948483-27e0ad55-15c3-4eef-b39e-94b68c37660e.png)\n\n# Transponder\nTransponder is an Object Relational Mapping(ORM) library for NoSQL databases. It's lightweight, with very small memory footprint.\nTransponder [dynamically generates bytecode](https://github.com/raphw/byte-buddy) over native DB client classes, so there are NO overheads for reflection and NO double storing of data.\n\n## Content\n\n1. [Use Cases](#use-cases)\n2. [Key Benefits](#key-benefits)\n3. [NoSQL Database Support Status](#nosql-database-support-status)\n4. [Java Version Requirements](#java-version-requirements)\n5. [Getting Started](#getting-started)\n6. [Defining DataModel](#defining-datamodel)\n7. [Transponder API](#transponder-api)\n8. [Transponder Annotations](#transponder-annotations)\n9. [Support of Multiple Dialects](#support-of-multiple-dialects)\n10. [Comparison With Other ORMs](#comparison-with-other-orms)\n11. [Suppport](#suppport)\n\n### Use Cases\nTransponder can be used for\n* Defining a data model in Java source code\n* Automatic creation of a datamodel in a NoSQL DB\n* Generation of Data Access Objects (DAO) - utility classes to work with data\n* Easy customization for specific needs, for example: introduce custom annotation `@Sudo` to execute code under priviledged access\n\n### Key Benefits\n\n* Lightweight\n* Small memory footprint\n* Transferable: datamodel defined for one DB can be reused for another one\n* Small learning curve\n\n### NoSQL Database Support Status\n\n| Database | Status | Type | Complexity | Java API Quality | Community | Performance | Maven Dependency |\n|----------|--------|------|------------|------------------|-----------|-------------|-------------------|\n| **Currently Supported** |\n| [OrientDB](https://github.com/orientechnologies/orientdb) | ✅ | Multi-Model | Medium | Excellent | Strong | High | `org.orienteer.transponder:transponder-orientdb` |\n| [ArcadeDB](https://github.com/ArcadeData/arcadedb) | ✅ | Multi-Model | Medium | Good | Growing | High | `org.orienteer.transponder:transponder-arcadedb` |\n| [Neo4j](https://github.com/neo4j/neo4j) | ✅ | Graph | Medium | Excellent | Very Strong | High | `org.orienteer.transponder:transponder-neo4j` |\n| [JanusGraph](https://github.com/JanusGraph/janusgraph) | ✅ | Graph | Low | Excellent | Strong | High | `org.orienteer.transponder:transponder-janusgraph` |\n| [MongoDB](https://github.com/mongodb/mongo) | ✅ | Document | Medium | Good | Very Strong | High | `org.orienteer.transponder:transponder-mongodb` |\n| **High Priority - Recommended Next** |\n| [ArangoDB](https://github.com/arangodb/arangodb) | 🔄 | Multi-Model | Medium | Good | Very Strong | High | `org.orienteer.transponder:transponder-arangodb` |\n| [CouchDB](https://github.com/apache/couchdb) | 🔄 | Document | Low | Good | Strong | Medium | `org.orienteer.transponder:transponder-couchdb` |\n| **Medium Priority - Strategic Extensions** |\n| [Redis](https://github.com/redis/redis) | 📋 | Key-Value | Low | Excellent | Very Strong | Very High | `org.orienteer.transponder:transponder-redis` |\n| [Memgraph](https://github.com/memgraph/memgraph) | 📋 | Graph | Very Low | Excellent | Growing | Very High | `org.orienteer.transponder:transponder-memgraph` |\n| **Lower Priority - Future Consideration** |\n| [Apache Cassandra](https://github.com/apache/cassandra) | 📋 | Wide Column | High | Excellent | Very Strong | High | `org.orienteer.transponder:transponder-cassandra` |\n| [Couchbase](https://github.com/couchbase) | 📋 | Document | Medium | Good | Strong | High | `org.orienteer.transponder:transponder-couchbase` |\n| [Hazelcast](https://github.com/hazelcast/hazelcast) | 📋 | Key-Value/Cache | Medium | Excellent | Strong | Very High | `org.orienteer.transponder:transponder-hazelcast` |\n| [DynamoDB](https://aws.amazon.com/dynamodb/) | 📋 | Key-Value/Document | High | Good | Strong | High | `org.orienteer.transponder:transponder-dynamodb` |\n\n**Legend:**\n- ✅ **Currently Supported** - Ready to use\n- 🔄 **High Priority** - Recommended for next implementation based on similarity to existing drivers and ecosystem fit\n- 📋 **Planned** - Future consideration based on community demand and strategic value\n\nPlease create an [issue](https://github.com/OrienteerBAP/Transponder/issues) or [discussion](https://github.com/OrienteerBAP/Transponder/discussions) if you need support of some other DBs or expedite priority for those which are not yet supported.\n\n## Java Version Requirements\n\n**Important**: Different Transponder modules have specific Java version requirements based on their underlying database dependencies:\n\n- **transponder-core**: Java 8+ (tested up to Java 21)\n- **transponder-orientdb**: Java 8+ (OrientDB 3.2.36 works with Java 8-21)\n- **transponder-arcadedb**: Java 11+ (ArcadeDB 23.12.1 requirement, works with Java 17+)\n- **transponder-neo4j**: Java 8-17 (Neo4j 4.4.38 fails with Java 21)\n- **transponder-janusgraph**: Java 8-11 (JanusGraph 1.1.0 limitation - requires explicit Java 11 compiler config)\n- **transponder-mongodb**: Java 8+ (MongoDB Java Driver 5.2.1 works with all Java versions)\n\n### Tested Java Version Compatibility Matrix\n\n| Module | Java 8 | Java 11 | Java 17 | Java 21 | Notes |\n|--------|---------|---------|---------|---------|-------|\n| **transponder-core** | ⚠️* | ✅ | ✅ | ✅ | *Requires Maven compiler config changes for Java 8 |\n| **transponder-orientdb** | ⚠️* | ✅ | ✅ | ✅ | *Requires Maven compiler config changes for Java 8 |\n| **transponder-arcadedb** | ❌ | ✅ | ✅ | ✅ | Minimum Java 11 required |\n| **transponder-neo4j** | ⚠️* | ✅ | ✅ | ❌ | *Requires Maven compiler config changes for Java 8; **Fails on Java 21** |\n| **transponder-janusgraph** | ⚠️* | ✅ | ❌ | ❌ | *Requires Maven compiler config changes for Java 8; Uses Java 11 compiler config |\n| **transponder-mongodb** | ⚠️* | ✅ | ✅ | ✅ | *Requires Maven compiler config changes for Java 8 |\n\n### Recommended Java Versions by Use Case\n\n#### For Maximum Compatibility\nUse **Java 11** - all modules work perfectly with Java 11.\n\n#### For Latest Java Features  \nUse **Java 17** with modules: core, orientdb, arcadedb, mongodb (excludes neo4j and janusgraph).\n\n#### Production Environments\n- **Java 11**: Safest choice, all modules tested and working\n- **Java 17**: Good choice if not using Neo4j or JanusGraph  \n- **Java 21**: Limited to core, orientdb, arcadedb, mongodb modules only\n\n### JanusGraph Distributed Graph Database\n\nThe JanusGraph module provides enterprise-grade distributed graph database capabilities that scale beyond Neo4j limitations:\n\n- **Massive Scalability**: Handle graphs with billions of vertices and edges across multiple machines\n- **Multiple Storage Backends**: Choose from Cassandra, HBase, or BerkeleyDB for storage\n- **Native TinkerPop Integration**: Full Apache TinkerPop 3.7.3 and Gremlin query support\n- **ACID Transactions**: Complete transactional support for data consistency\n- **High Availability**: Built-in replication and fault tolerance\n\nUse JanusGraph when you need distributed graph processing or when your graph data exceeds single-machine capabilities.\n\nFor development environments with multiple Java versions, consider using tools like `jenv` or `SDKMAN!` to manage Java versions per project.\n\n## Getting Started\n\n**Before you start**: Check the [Java Version Requirements](#java-version-requirements) section above to ensure your environment meets the requirements for your target database.\n\nAdd the following dependency into your `pom.xml`:\n\n```xml\n\u003cdependency\u003e\n   \u003cgroupId\u003eorg.orienteer.transponder\u003c/groupId\u003e\n   \u003cartifactId\u003etransponder-${NOSQL DB NAME}\u003c/artifactId\u003e\n   \u003cversion\u003e${project.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nIf you are using `SNAPSHOT` version, please make sure that the following repository is included into your `pom.xml`:\n\n```xml\n\u003crepository\u003e\n\t\u003cid\u003eSonatype Nexus\u003c/id\u003e\n\t\u003curl\u003ehttps://oss.sonatype.org/content/repositories/snapshots/\u003c/url\u003e\n\t\u003creleases\u003e\n\t\t\u003cenabled\u003efalse\u003c/enabled\u003e\n\t\u003c/releases\u003e\n\t\u003csnapshots\u003e\n\t\t\u003cenabled\u003etrue\u003c/enabled\u003e\n\t\u003c/snapshots\u003e\n\u003c/repository\u003e\n```\n\n## Defining DataModel\n\nUse interface class with annotation `@EntityType(\"EntryTypeName\")` to define a type from your data-model. All getters and setters will be mapped to corresponding properties/columns of an entity in a database. You can use interface **default** methods for your custom methods. There is a set of annotations supported by Transponder to simplify work with the data model: `@EntityIndex`, `@Query`, `@Lookup`, `@Command` and etc. Please see corresponding chapter for details. Lets create simple datamodel to mimic file-system:\n\n```java\n@EntityType(\"Entry\")\n@EntityIndex(name = \"nameParent\", properties = {\"name\", \"parent\"})\npublic interface IEntry {\n\n\tpublic String getName();\n\tpublic void setName(String value);\n\t\n\tpublic IFolder getParent();\n\tpublic void setParent(IFolder value);\n\t\n\t@Lookup(\"select from Entry where name=:name and parent=:parent\")\n\tpublic boolean lookupByName(String name, IFolder parent);\n  \n  \tpublic default String getFullPath() {\n\t\tIFolder parent = getParent();\n\t\treturn (parent!=null?parent.getFullPath():\"\")+\"/\"+getName();\n\t}\n}\n\n@EntityType(\"Folder\")\npublic interface IFolder extends IEntry {\n\n\tpublic List\u003cIEntry\u003e getChild();\n\tpublic void setChild(List\u003cIEntry\u003e value);\n}\n\n@EntityType(\"File\")\npublic interface IFile extends IEntry {\n\n\tpublic byte[] getContent();\n\tpublic void setContent(byte[] value);\n\t\n}\n```\nAfter calling `transponder.define(IFile.class, IFolder.class)` Transponder will create the following datamodel in a database:\n![image](https://user-images.githubusercontent.com/1199285/139164433-88eb9612-447e-4061-b452-c0035dcf6d37.png)\n\nAdditionally you can create Data Access Object to be able to query/modify your data:\n\n```java\npublic interface IFileSystem {\n\t\n\t@Query(\"select from Folder where name = :name and parent is null\")\n\tpublic IFolder getRoot(String name);\n\t\n\t@Query(\"select from Entry where name=:name and parent=:parent\")\n\tpublic IEntry lookupByName(String name, IFolder parent);\n\t\n\t@Query(\"select from Entry where name like :search\")\n\tpublic List\u003cIEntry\u003e search(String search);\n\t\n\t@Command(\"delete from File where content is null\")\n\tpublic void removeEmpty();\n}\n```\n\n## Transponder API\n\nTo create **Transponder** instance:\n```java\nTransponder transponder = new Transponder(driver);\n//For example:\nTransponder transponder = new Transponder(new ODriver()); //OrientDB\nTransponder transponder = new Transponder(new ArcadeDBDriver(arcadeDatabase)); //ArcadeDB\n```\n\nTo define datamodel in a database:\n```java\ntransponder.define(IFolder.class, IFile.class, IMyOtherEntity.class, ...);\n```\n\nTo create DAO instance from the specified interface or class:\n```java\nIFileSystem fsDao = transponder.dao(IFileSystem.class);\nIFileSystem fsDao = transponder.dao(IFileSystem.class, IOtherDAOClass.class, IYetAnotherDAOClass.class, ...);\n```\n\nAfter DAO creation you can use it right away:\n```java\nList\u003cIEntry\u003e textFiles = fsDao.search(\"%.txt\");\n```\n\nTo create new wrapped entity:\n```java\nIFolder folder = transponder.create(IFolder.class);\nIFolder folder = transponder.create(IFolder.class, IMyOtherUsefullWrapper.class, ...);\n```\n\nAfter creation of an entity you can work with it as usual java object:\n```java\nfolder.setName(\"My Cool Folder\");\nfolder.setParent(myOtherFolder);\nString fullPath = folder.getFullPath();\n```\n\nTo persist/save entity into DB:\n\n```java\nTranponder.save(folder);\n```\n\nOr you can do simply `folder.save()` if you mixin the following method into your wrapper:\n\n```\npublic default IEntry save() {\n  Transponder.save();\n  return this;\n}\n```\n\nAlso you can wrap some existing entity from a database into wrapped one. Example for OrientDB:\n```java\nODocument myFolderDoc = ...;\nIFolder folder = transponder.provide(myFolderDoc, IFolder.class);\nIFolder folder = transponder.provide(myFolderDoc, IFolder.class, IMyOtherUsefulWrapper.class, ...); //To mixin other useful interfaces\nIFodler folder = transponder.wrap(myFolderDoc); //More generic version, but corresponding wrapper should be defined by transponder.define(...) in this case\n```\n\nIf needed, you can unwrap entity as well. Example for OrientDB:\n```java\nODocument myFolderDoc = (ODocument)Transponder.unwrap(folder);\n```\n\nSometimes it's useful to rewrap the same entity but into different class.\n```java\nMyNewWrapper newWrapper = Transponder.rewrap(oldWrapper, MyNewWrapper.class, SomeOtherInterface.class, ...);\n```\n\nAlso you can upgrade existing wrapper by adding more interfaces to be supported\n```java\nMyEntity myEntity = ...;\nmyEntity = Transponder.upgrade(myEntity, SomeNewInterface.class, SomeOtherInterface.class);\n```\n\nIf you have wrapped entity and you need obtain Transponder:\n```java\nTransponder transponder = Transponder.getTransponder(folder);\n```\n\n## Transponder Annotations\n\n| Annotation | Description |\n|------------|-------------|\n|`@EntityType`|Current class defines entity type|\n|`@EntityIndex/@EntityIndexes`|Creates indexes on the entity type in a database|\n|`@EntityProperty`|This getter/setter method should be mapped to corresponding property of an entity in a database|\n|`@EntityPropertyIndex`|Creates index in a datasource on current property|\n|`@Query`|Method execute query in a database and return corresponding result|\n|`@Lookup`|Lookup database for an entity according to search criterias and if found: replace underling entity of the current wrapper|\n|`@Command`|Execute some command in a database|\n|`@DefaultValue`|Return provided default value if actual result from this method is null|\n|`@OrientDBProperty`|OrientDB specific additional settings for the property|\n|`@ArcadeDBProperty`|ArcadeDB specific additional settings for the property|\n\nAnnotations in bytecode generation within Transponder is very flexible (due to [Byte Buddy](https://github.com/raphw/byte-buddy)) and can be easily extended to support custom cases. For example: `@Sudo` - to execute some method under super user, `@Count` - to count number of invokations for metrics and etc.\n\n### Support of Multiple Dialects\nQueries and commands for the same functions might vary for different databases. Valid SQL for one NoSQL database, might require correction for another one. That's why **Transponder** supports polyglot definitions for `@Query`, `@Lookup` and `@Command`. **Transponder** do translation to corresponding dialect during dynamic generation of a wrapper, so there is no overheads during actual runtime. Every query/command has **id**. It's either can be defined manually (for example `@Query(id=\"myQuery\", value=\"select ...\")`) or generated automatically (for example first query for `IFileSystem` above will have id `\u003cfullpackagename\u003e.IFileSystem.getRoot`. Then **Transponder** uses provided resource file by path `/META-INF/transponder/polyglot.properties` to lookup proper query for a specific dialect. For example, for query with id `myQuery` for OrientDB library will look for keys `orientdb.myQuery` and `orientdb.myQuery.language`. If first one is found - it will be used as actual query for OrientDB. If second one was also found: correspinding language will overload language defined in actual annotation.\n\n## Comparison With Other ORMs\n\n|              | **Transponder** | **Spring Data** | **Hibernate** | **MyBatis** |\n|--------------|-----------------|-----------------|---------------|-------------|\n|NoSQL Support|:white_check_mark:|:white_check_mark:|:white_check_mark:|:x:|\n|Universal DataModel Markup|:white_check_mark:|:x:|:x:|:x:|\n|No Double Caching|:white_check_mark:|:x:|:x:|:x:|\n|Easy Extendability On User Level Code|:white_check_mark:|:x:|:x:|:x:|\n|Easy SPI For New Drivers|:white_check_mark:|:x:|:x:|:x:|\n|Support of Multi-Inheritance|:white_check_mark:|:x:|:x:|:x:|\n\n**Disclaimer**: Comparison might be subjective. If you have comments: please create an issue or discussion\n\n## Suppport\n\nIf you need any support or questions please create an [issue](https://github.com/OrienteerBAP/Transponder/issues) or [discussion](https://github.com/OrienteerBAP/Transponder/discussions).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forienteerbap%2Ftransponder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forienteerbap%2Ftransponder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forienteerbap%2Ftransponder/lists"}