{"id":13804786,"url":"https://github.com/buggins/hibernated","last_synced_at":"2025-05-13T18:32:50.102Z","repository":{"id":7986377,"uuid":"9391449","full_name":"buggins/hibernated","owner":"buggins","description":"HibernateD is ORM for D language (similar to Hibernate)","archived":false,"fork":false,"pushed_at":"2024-12-22T21:33:27.000Z","size":1119,"stargazers_count":82,"open_issues_count":19,"forks_count":31,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-12-22T22:24:21.422Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"D","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/buggins.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2013-04-12T09:59:10.000Z","updated_at":"2024-12-22T21:33:31.000Z","dependencies_parsed_at":"2023-11-26T12:27:10.634Z","dependency_job_id":"e53ab614-7650-496d-a0d8-5859d959ab7a","html_url":"https://github.com/buggins/hibernated","commit_stats":null,"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buggins%2Fhibernated","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buggins%2Fhibernated/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buggins%2Fhibernated/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buggins%2Fhibernated/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/buggins","download_url":"https://codeload.github.com/buggins/hibernated/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254003450,"owners_count":21997889,"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":[],"created_at":"2024-08-04T01:00:53.933Z","updated_at":"2025-05-13T18:32:49.683Z","avatar_url":"https://github.com/buggins.png","language":"D","funding_links":[],"categories":["Database clients"],"sub_categories":["XML"],"readme":"HibernateD\n==========\n\n[![DUB Package](https://img.shields.io/dub/v/hibernated.svg)](https://code.dlang.org/packages/hibernated) [![GitHub CI](https://github.com/buggins/hibernated/actions/workflows/dub.yml/badge.svg)](https://github.com/buggins/hibernated/actions/workflows/dub.yml) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/buggins/hibernated?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nHibernateD is ORM for D language (similar to Hibernate)\n\nThe project is hosted on [github](https://github.com/buggins/hibernated) with documentation available on the [wiki](https://github.com/buggins/hibernated/wiki).\n\nUses [DDBC](https://github.com/buggins/ddbc) as an abstraction layer for the underlying database. DDBC currently supports SQLite, MySQL, Postgres, SQL Server, and potentially Oracle.\n\n## SQL dialects supported by Hibernated\n\nCurrently hiberanted supports:\n\n - SQLite (requires SQLite v3.7.11 or later)\n - MySQL (tests are run against mysql v5.7)\n - Postgres\n\nBut since the underlying DDBC library now has ODBC support some work is underway to also add\n\n - SQL Server (2017 \u0026 2019)\n - Oracle (due to the size of the docker image for Oracle this may not be tested during CI)\n\n## Sample code:\n\n```D\nimport hibernated.core;\nimport std.algorithm;\n\n\n// Annotations of entity classes\n\nclass User {\n    long id;\n    string name;\n    Customer customer;\n    @ManyToMany // cannot be inferred, requires annotation\n        LazyCollection!Role roles;\n}\n\nclass Customer {\n    int id;\n    string name;\n    // Embedded is inferred from type of Address\n    Address address;\n\n    Lazy!AccountType accountType; // ManyToOne inferred\n\n    User[] users; // OneToMany inferred\n\n    this() {\n        address = new Address();\n    }\n}\n\n@Embeddable\nclass Address {\n    string zip;\n    string city;\n    string streetAddress;\n}\n\nclass AccountType {\n    int id;\n    string name;\n}\n\nclass Role {\n    int id;\n    string name;\n    @ManyToMany // w/o this annotation will be OneToMany by convention\n        LazyCollection!User users;\n}\n\nint main() {\n\n    // create metadata from annotations\n    EntityMetaData schema = new SchemaInfoImpl!(User, Customer, AccountType, \n            Address, Role);\n\n\n\n\n    // setup DB connection factory\n    version (USE_MYSQL) {\n        import ddbc.drivers.mysqlddbc;\n        MySQLDriver driver = new MySQLDriver();\n        string url = MySQLDriver.generateUrl(\"localhost\", 3306, \"test_db\");\n        string[string] params = MySQLDriver.setUserAndPassword(\"testuser\", \"testpasswd\");\n        Dialect dialect = new MySQLDialect();\n    } else {\n        import ddbc.drivers.sqliteddbc;\n        SQLITEDriver driver = new SQLITEDriver();\n        string url = \"zzz.db\"; // file with DB\n        static import std.file;\n        if (std.file.exists(url))\n            std.file.remove(url); // remove old DB file\n        string[string] params;\n        Dialect dialect = new SQLiteDialect();\n    }\n    DataSource ds = new ConnectionPoolDataSourceImpl(driver, url, params);\n\n\n    // create session factory\n    SessionFactory factory = new SessionFactoryImpl(schema, dialect, ds);\n    scope(exit) factory.close();\n\n    // Create schema if necessary\n    {\n        // get connection\n        Connection conn = ds.getConnection();\n        scope(exit) conn.close();\n        // create tables if not exist\n        factory.getDBMetaData().updateDBSchema(conn, false, true);\n    }\n\n    // Now you can use HibernateD\n\n    // create session\n    Session sess = factory.openSession();\n    scope(exit) sess.close();\n\n    // use session to access DB\n\n    // read all users using query\n    Query q = sess.createQuery(\"FROM User ORDER BY name\");\n    User[] list = q.list!User();\n\n    // create sample data\n    Role r10 = new Role();\n    r10.name = \"role10\";\n    Role r11 = new Role();\n    r11.name = \"role11\";\n    Customer c10 = new Customer();\n    c10.name = \"Customer 10\";\n    c10.address = new Address();\n    c10.address.zip = \"12345\";\n    c10.address.city = \"New York\";\n    c10.address.streetAddress = \"Baker st., 12\";\n    User u10 = new User();\n    u10.name = \"Alex\";\n    u10.customer = c10;\n    u10.roles = [r10, r11];\n    sess.save(r10);\n    sess.save(r11);\n    sess.save(c10);\n    sess.save(u10);\n\n    // load and check data\n    User u11 = sess.createQuery(\"FROM User WHERE name=:Name\").\n        setParameter(\"Name\", \"Alex\").uniqueResult!User();\n    assert(u11.roles.length == 2);\n    assert(u11.roles[0].name == \"role10\" || u11.roles.get()[0].name == \"role11\");\n    assert(u11.roles[1].name == \"role10\" || u11.roles.get()[1].name == \"role11\");\n    assert(u11.customer.name == \"Customer 10\");\n    assert(u11.customer.users.length == 1);\n    assert(u11.customer.users[0] == u10);\n    assert(u11.roles[0].users.length == 1);\n    assert(u11.roles[0].users[0] == u10);\n\n    // remove reference\n    u11.roles = u11.roles().remove(0);\n    sess.update(u11);\n\n    // remove entity\n    sess.remove(u11);\n    return 0;\n}\n```\n\n## Additional Features\n\n### Composite Keys\n\nIf a database contains tables with a composite primary key, the `@EmbeddedId` can be used to\nrepresent this. The columns that represent the primary key should be in an `@Embeddable` class\nwhich is then referenced in a property annotated with `@EmbeddedId`.\n\nFor example, consider a database table created via the following SQL command:\n\n```sql\nCREATE TABLE invoices (\n    vendor_no VARCHAR(8) NOT NULL,\n    invoice_no VARCHAR(20) NOT NULL,\n    amount_e4 INTEGER);\nALTER TABLE invoices\n    ADD CONSTRAINT invoices_pkey PRIMARY KEY (vendor_no, invoice_no);\r\n```\n\nTo represent this using HibernateD, the following code would be used:\n```\n@Embeddable\nclass InvoiceId {\n    string vendorNo;\n    string invoiceNo;\n\n    // Be sure to implement this to benefit from session caching.\n    bool opEquals(const InvoiceId o) const @safe {\n        return vendorNo == o.vendorNo \u0026\u0026 invoiceNo == o.invoiceNo;\n    }\n}\n\n@Table(\"invoices\")\nclass Invoice {\n    @EmbeddedId InvoiceId invoiceId;\n    int amountE4;\n}\n```\n\n**Note**: At the time of writing, there are important limitations.\n1. The function `DBInfo.updateDbSchema(Connection conn, bool dropTables, bool createTables)`\n   does not generate schemas with compound keys.\n2. The Hibernate annotation `@JoinColumns` (plural) has not yet been implemented, thus,\n   the `@ManyToOne` and `@ManyToMany` relations are not usable for classes using an\n   `@EmbeddedId`.\n3. The `@Embedded` class referenced via an `@EmbeddedId` property should implement `opEquals`\n   in order to gain performance benefits from session caching.\nThese features will be added in future updates.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuggins%2Fhibernated","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbuggins%2Fhibernated","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuggins%2Fhibernated/lists"}