buggins / hibernated

HibernateD is ORM for D language (similar to Hibernate)
82 stars 31 forks source link

Range violation when using more than one OneToMany fields #48

Closed KrzaQ closed 5 years ago

KrzaQ commented 7 years ago
import hibernated.core, hibernated.session;
import ddbc.drivers.sqliteddbc;
import std.algorithm;
import std.stdio;

class ForumUser
{
    @Generated @Id int id;
    Post[] posts; // <--
    IPAddr[] ips; // <--
    string name;
}

class Post
{
    @Generated @Id int id;
    ForumUser user;
}

class IPAddr
{
    @Generated @Id int id;
    ForumUser user;
}

int main()
{
    EntityMetaData schema = new SchemaInfoImpl!(ForumUser, Post, IPAddr);

    SQLITEDriver driver = new SQLITEDriver();
    string url = "zzz.db"; // file with DB
    static import std.file;
    if (std.file.exists(url))
        std.file.remove(url); // remove old DB file
    string[string] params;
    Dialect dialect = new SQLiteDialect();
    DataSource ds = new ConnectionPoolDataSourceImpl(driver, url, params);

    SessionFactory factory = new SessionFactoryImpl(schema, dialect, ds);
    scope(exit) factory.close();

    {
        Connection conn = ds.getConnection();
        scope(exit) conn.close();
        factory.getDBMetaData().updateDBSchema(conn, false, true);
    }

    Session sess = factory.openSession();
    scope(exit) sess.close();

    auto u = new ForumUser;
    u.name = "foo";
    sess.save(u);

    ForumUser[] users = sess.createQuery("FROM ForumUser").list!ForumUser;

    return 0;
}

In the above example, commenting out either Post[] posts; or IPAddr[] ips; makes the example compile and run. Otherwise, I get the following:

Running ./multi_fail
core.exception.RangeError@../../.dub/packages/hibernated-0.2.33/hibernated/source/hibernated/session.d(801): Range violation
----------------
??:? _d_arraybounds [0x7a68f3]
??:? hibernated.session.__array [0x68f1b1]
../../.dub/packages/hibernated-0.2.33/hibernated/source/hibernated/session.d:801 hibernated.session.PropertyLoadItem hibernated.session.PropertyLoadMap.remove(const(hibernated.metadata.PropertyInfo)) [0x694890]
../../.dub/packages/hibernated-0.2.33/hibernated/source/hibernated/session.d:973 void hibernated.session.QueryImpl.delayedLoadRelations(hibernated.session.PropertyLoadMap) [0x695c1a]
../../.dub/packages/hibernated-0.2.33/hibernated/source/hibernated/session.d:1083 Object[] hibernated.session.QueryImpl.listObjects(Object, hibernated.session.PropertyLoadMap) [0x696a00]
../../.dub/packages/hibernated-0.2.33/hibernated/source/hibernated/session.d:1050 Object[] hibernated.session.QueryImpl.listObjects(Object) [0x69671b]
../../.dub/packages/hibernated-0.2.33/hibernated/source/hibernated/session.d:964 Object[] hibernated.session.QueryImpl.listObjects() [0x695b6a]
../../.dub/packages/hibernated-0.2.33/hibernated/source/hibernated/session.d:151 app.ForumUser[] hibernated.session.Query.list!(app.ForumUser).list() [0x682e3c]
source/app.d:60 _Dmain [0x6547a8]
??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0x7acd2e]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x7acc74]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x7accea]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x7acc74]
??:? _d_run_main [0x7acbee]
??:? main [0x684ab1]
??:? __libc_start_main [0x91aef290]
Program exited with code 1

The function delayedLoadRelations (session.d:973) seems suspicious, but as of now I wasn't able to make it work.