New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return rows from a child table that aren't connected to a parent? #61

Closed
ggunders opened this Issue Jul 24, 2015 · 10 comments

Comments

Projects
None yet
3 participants
@ggunders

ggunders commented Jul 24, 2015

Lets say i have a data model like this:

public class woman{
private String name;
private Breast left_breast;
private Breast right_breast;
... more (_id), etc
}

public Breast{
private String size;
private String Manufacturer;
private String fillType;
.... more (_id), etc
}

The server feeds the app women with breasts, where woman and breasts have a unique server ID(not shown). in some parts of the app, i want to show the woman with the correct breasts. but in another part of the app i want to just show breasts.

breasts are child elements of women, but are also loaded independently from the server so that all the breast types are viewable on the app.

when i do RushSearch.find(Breast.class) i get lots of duplicates because breasts are loaded by the parent and seperately from the server sync service.

how can i just get a unique list of breasts, is there a way to do a RushSearch().whereParentless() - something that gives me all the breasts that arent connected to a woman/parent? maybe i want a unique android spinner of all the breast types.

or should i be loading the breasts table first, then load the woman table and do a lookup on every woman object that comes in from the network service and find the breast child element first, assign it to the woman object and save it?

if two women have the exact same breasts, should they both be connected to the same child element or should i be creating duplicate breast child elements.

based on the response to this post, ill get into adding a Man class with the need for those Breast child element. - thx Kardashians

@Stuart-campbell

This comment has been minimized.

Show comment
Hide comment
@Stuart-campbell

Stuart-campbell Jul 24, 2015

Owner

Hi,

I think I have grasped your breasts issue.

What you want is to register your breasts with RushCore so that there will only be one row in the database per breast. This is all dependent on the server ids being a constant across the same breasts regardless of which request they come from.

// Call before save
RushCore.getInstance().registerObjectWithId(breast, breastServerId);

This will also mean woman who share the same breast type will be linked to the save row and the getId method will return your server id.

On the children you may want to add

@RushDisableAutodelete
private Breast left_breast;
@RushDisableAutodelete
private Breast right_breast;

Other wise the children will be deleted when the parent is which if the children are used in multiple places would be a problem.

Thanks

Owner

Stuart-campbell commented Jul 24, 2015

Hi,

I think I have grasped your breasts issue.

What you want is to register your breasts with RushCore so that there will only be one row in the database per breast. This is all dependent on the server ids being a constant across the same breasts regardless of which request they come from.

// Call before save
RushCore.getInstance().registerObjectWithId(breast, breastServerId);

This will also mean woman who share the same breast type will be linked to the save row and the getId method will return your server id.

On the children you may want to add

@RushDisableAutodelete
private Breast left_breast;
@RushDisableAutodelete
private Breast right_breast;

Other wise the children will be deleted when the parent is which if the children are used in multiple places would be a problem.

Thanks

@ggunders

This comment has been minimized.

Show comment
Hide comment
@ggunders

ggunders Jul 24, 2015

ok i see what your laying down.

Register the Breast object first with the core.

then when the server delivers the List womanList -- from the network service i do something like this:

for(Woman woman : womanList){
// get leftBreast ID, do a RushSearch.whereID(breastID);
woman.setLeftBreast(object from above search)
// lookup rightBreast
woman.setRightBreast(object form above search)
woman.save();
}

i've saved the woman list from the server with the child elements i've already registered with the RushCore. When i refresh the local database, i clear the tables with deleteAll(Breast.class) and deleteAll(Woman.class) and repeat what i did above. this makes sense so far.

now if i wanted to create a new breast type on the app and push to the server, i can use the standard save method without registering with an ID, i would just need to flag that row that it hasn't been synced with the server. like a cached boolean value.

thanks so much ill keep playing. i did submit an issue with looking up child elements and saving them to new parents. ill try to reproduce using this flow.

thx

ggunders commented Jul 24, 2015

ok i see what your laying down.

Register the Breast object first with the core.

then when the server delivers the List womanList -- from the network service i do something like this:

for(Woman woman : womanList){
// get leftBreast ID, do a RushSearch.whereID(breastID);
woman.setLeftBreast(object from above search)
// lookup rightBreast
woman.setRightBreast(object form above search)
woman.save();
}

i've saved the woman list from the server with the child elements i've already registered with the RushCore. When i refresh the local database, i clear the tables with deleteAll(Breast.class) and deleteAll(Woman.class) and repeat what i did above. this makes sense so far.

now if i wanted to create a new breast type on the app and push to the server, i can use the standard save method without registering with an ID, i would just need to flag that row that it hasn't been synced with the server. like a cached boolean value.

thanks so much ill keep playing. i did submit an issue with looking up child elements and saving them to new parents. ill try to reproduce using this flow.

thx

@ggunders

This comment has been minimized.

Show comment
Hide comment
@ggunders

ggunders Jul 24, 2015

Ok, this all seems to be working like expected. however there is one bug

i first load the breasts with registerobjectasid

then i load the women without registering there ID.

if both breasts are the same i have no issues, but when the breasts are different child objects i do this

iterate over list of women:
set right breast to a looked up breast object
set left breast to a looked up difference breast object
save()

then RushSearch.find(Woman.class)
i get a null for the left breast, but a valid right breast.

similar to the issue i logged #54

the woman table has two entries, the woman breast join table has the correct entries which map women to breasts with the correct ID values, and finally there are 3 breast records with the correct ID's.

it something with the RushSearch.find method that gets confused when a parent object has two of the same type of children but are different child obejcts like Breast leftBreast and Breast rightBreast.

appreciate the help, this is a show stopper for me. thx

ggunders commented Jul 24, 2015

Ok, this all seems to be working like expected. however there is one bug

i first load the breasts with registerobjectasid

then i load the women without registering there ID.

if both breasts are the same i have no issues, but when the breasts are different child objects i do this

iterate over list of women:
set right breast to a looked up breast object
set left breast to a looked up difference breast object
save()

then RushSearch.find(Woman.class)
i get a null for the left breast, but a valid right breast.

similar to the issue i logged #54

the woman table has two entries, the woman breast join table has the correct entries which map women to breasts with the correct ID values, and finally there are 3 breast records with the correct ID's.

it something with the RushSearch.find method that gets confused when a parent object has two of the same type of children but are different child obejcts like Breast leftBreast and Breast rightBreast.

appreciate the help, this is a show stopper for me. thx

@Stuart-campbell

This comment has been minimized.

Show comment
Hide comment
@Stuart-campbell

Stuart-campbell Jul 24, 2015

Owner

Have you tried just registering the left and right breast rather than looking them up? That should just mean it won't matter how many times you save the same breast it will just keep overwrite the same row?

Not able to looking into the bug this weekend but will hope to get a fix in, in the next week or two.

Thanks

Owner

Stuart-campbell commented Jul 24, 2015

Have you tried just registering the left and right breast rather than looking them up? That should just mean it won't matter how many times you save the same breast it will just keep overwrite the same row?

Not able to looking into the bug this weekend but will hope to get a fix in, in the next week or two.

Thanks

@ggunders

This comment has been minimized.

Show comment
Hide comment
@ggunders

ggunders Jul 24, 2015

The app flow is that a woman is built in a wizard, where breast objects are selected. but the wizard just knows about the breast names not the breast id, so a lookup is required. i can reproduce without a lookup. see below

I can include the classes, but they are pretty minimal.

 // clear tables
    RushCore.getInstance().deleteAll(Woman.class);
    RushCore.getInstance().deleteAll(Breast.class);
  // load up the breasts

    Breast b1 = new Breast(1,"A");
    Breast b2 = new Breast(2,"B");

    RushCore.getInstance().registerObjectWithId(b1, String.valueOf(b1.getServerID()));
    RushCore.getInstance().registerObjectWithId(b2, String.valueOf(b2.getServerID()));

    b1.save();
    b2.save();

    // load women

    Woman betty = new Woman();
    betty.setAge(22);
    betty.setName("betty");
    betty.setlBreast(b1);
    betty.setrBreast(b1);
    betty.setServerID(12);// not important now
    betty.save();

    Woman wilma = new Woman();
    wilma.setName("Wilma");
    wilma.setAge(32);
    wilma.setlBreast(b1);
    wilma.setrBreast(b1);
    betty.setServerID(13);// not important now
    wilma.save();

    // get all the ladies
    List<Woman> ladies = new RushSearch().find(Woman.class);

    System.out.println(ladies.toString());

Output:
I/System.out﹕ Initializing RUSH ORM!!
I/System.out﹕ [Woman{serverID=12, name='betty', age=22, lBreast=null, rBreast=Breast{serverID=1, size='A'}}, Woman{serverID=0, name='Wilma', age=32, lBreast=null, rBreast=Breast{serverID=1, size='A'}}]
07-24 21:38:35.267 22688-22723/com.threetwofour.plasticsurgery D/OpenGLRenderer﹕

Notice how lBreast is null for both ladies?

if i set both ladies up for different breasts (per woman) it works:

    betty.setlBreast(b1);
    betty.setrBreast(b2);

    betty.setlBreast(b1);
    betty.setrBreast(b2);

strangly enough when i switch back and forth between setting the breasts the same vs different i get the following until i erase rush.db and the NPE exception goes away. if i dont erase the rush.db file, this exception keeps popping.

 Process: com.threetwofour.plasticsurgery, PID: 17327
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.threetwofour.plasticsurgery/com.threetwofour.plasticsurgery.MainActivity}: java.lang.NullPointerException: Null pointer exception during instruction 'invoke-static {v4}, co.uk.rushorm.core.Rush co.uk.rushorm.core.implementation.ReflectionClassLoader$Join.access$100(co.uk.rushorm.core.implementation.ReflectionClassLoader$Join) // method@551'
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
        at android.app.ActivityThread.access$800(ActivityThread.java:144)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.NullPointerException: Null pointer exception during instruction 'invoke-static {v4}, co.uk.rushorm.core.Rush co.uk.rushorm.core.implementation.ReflectionClassLoader$Join.access$100(co.uk.rushorm.core.implementation.ReflectionClassLoader$Join) // method@551'
        at co.uk.rushorm.core.implementation.ReflectionClassLoader$1$1.attach(ReflectionClassLoader.java:195)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.loadClasses(ReflectionClassLoader.java:57)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader$1.doAction(ReflectionClassLoader.java:183)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.doLoop(ReflectionClassLoader.java:257)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.addChildrenToList(ReflectionClassLoader.java:158)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.loadClasses(ReflectionClassLoader.java:63)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.loadClasses(ReflectionClassLoader.java:42)
        at co.uk.rushorm.core.RushCore.load(RushCore.java:608)
        at co.uk.rushorm.core.RushCore.load(RushCore.java:257)
        at co.uk.rushorm.core.RushSearch.find(RushSearch.java:41)
        at com.threetwofour.plasticsurgery.MainActivity.onCreate(MainActivity.java:56)
        at android.app.Activity.performCreate(Activity.java:5933)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)

            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

version 1.1.7

ggunders commented Jul 24, 2015

The app flow is that a woman is built in a wizard, where breast objects are selected. but the wizard just knows about the breast names not the breast id, so a lookup is required. i can reproduce without a lookup. see below

I can include the classes, but they are pretty minimal.

 // clear tables
    RushCore.getInstance().deleteAll(Woman.class);
    RushCore.getInstance().deleteAll(Breast.class);
  // load up the breasts

    Breast b1 = new Breast(1,"A");
    Breast b2 = new Breast(2,"B");

    RushCore.getInstance().registerObjectWithId(b1, String.valueOf(b1.getServerID()));
    RushCore.getInstance().registerObjectWithId(b2, String.valueOf(b2.getServerID()));

    b1.save();
    b2.save();

    // load women

    Woman betty = new Woman();
    betty.setAge(22);
    betty.setName("betty");
    betty.setlBreast(b1);
    betty.setrBreast(b1);
    betty.setServerID(12);// not important now
    betty.save();

    Woman wilma = new Woman();
    wilma.setName("Wilma");
    wilma.setAge(32);
    wilma.setlBreast(b1);
    wilma.setrBreast(b1);
    betty.setServerID(13);// not important now
    wilma.save();

    // get all the ladies
    List<Woman> ladies = new RushSearch().find(Woman.class);

    System.out.println(ladies.toString());

Output:
I/System.out﹕ Initializing RUSH ORM!!
I/System.out﹕ [Woman{serverID=12, name='betty', age=22, lBreast=null, rBreast=Breast{serverID=1, size='A'}}, Woman{serverID=0, name='Wilma', age=32, lBreast=null, rBreast=Breast{serverID=1, size='A'}}]
07-24 21:38:35.267 22688-22723/com.threetwofour.plasticsurgery D/OpenGLRenderer﹕

Notice how lBreast is null for both ladies?

if i set both ladies up for different breasts (per woman) it works:

    betty.setlBreast(b1);
    betty.setrBreast(b2);

    betty.setlBreast(b1);
    betty.setrBreast(b2);

strangly enough when i switch back and forth between setting the breasts the same vs different i get the following until i erase rush.db and the NPE exception goes away. if i dont erase the rush.db file, this exception keeps popping.

 Process: com.threetwofour.plasticsurgery, PID: 17327
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.threetwofour.plasticsurgery/com.threetwofour.plasticsurgery.MainActivity}: java.lang.NullPointerException: Null pointer exception during instruction 'invoke-static {v4}, co.uk.rushorm.core.Rush co.uk.rushorm.core.implementation.ReflectionClassLoader$Join.access$100(co.uk.rushorm.core.implementation.ReflectionClassLoader$Join) // method@551'
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
        at android.app.ActivityThread.access$800(ActivityThread.java:144)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.NullPointerException: Null pointer exception during instruction 'invoke-static {v4}, co.uk.rushorm.core.Rush co.uk.rushorm.core.implementation.ReflectionClassLoader$Join.access$100(co.uk.rushorm.core.implementation.ReflectionClassLoader$Join) // method@551'
        at co.uk.rushorm.core.implementation.ReflectionClassLoader$1$1.attach(ReflectionClassLoader.java:195)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.loadClasses(ReflectionClassLoader.java:57)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader$1.doAction(ReflectionClassLoader.java:183)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.doLoop(ReflectionClassLoader.java:257)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.addChildrenToList(ReflectionClassLoader.java:158)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.loadClasses(ReflectionClassLoader.java:63)
        at co.uk.rushorm.core.implementation.ReflectionClassLoader.loadClasses(ReflectionClassLoader.java:42)
        at co.uk.rushorm.core.RushCore.load(RushCore.java:608)
        at co.uk.rushorm.core.RushCore.load(RushCore.java:257)
        at co.uk.rushorm.core.RushSearch.find(RushSearch.java:41)
        at com.threetwofour.plasticsurgery.MainActivity.onCreate(MainActivity.java:56)
        at android.app.Activity.performCreate(Activity.java:5933)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)

            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

version 1.1.7

@ggunders

This comment has been minimized.

Show comment
Hide comment
@ggunders

ggunders Jul 24, 2015

the classes:

@RushTableAnnotation
public class Woman extends RushObject {

private long serverID;
private String name;
private long age;
private Breast lBreast;
private Breast rBreast;

public Woman(){}

@RushTableAnnotation
public class Breast extends RushObject {

private long serverID;
private String size;

public Breast(){}

public Breast(long id, String size) {
    this.size = size;
    this.serverID = id;
}

ggunders commented Jul 24, 2015

the classes:

@RushTableAnnotation
public class Woman extends RushObject {

private long serverID;
private String name;
private long age;
private Breast lBreast;
private Breast rBreast;

public Woman(){}

@RushTableAnnotation
public class Breast extends RushObject {

private long serverID;
private String size;

public Breast(){}

public Breast(long id, String size) {
    this.size = size;
    this.serverID = id;
}
@ggunders

This comment has been minimized.

Show comment
Hide comment
@ggunders

ggunders Jul 30, 2015

Still really need a second look at this issue. Thx

ggunders commented Jul 30, 2015

Still really need a second look at this issue. Thx

@aercanozcan

This comment has been minimized.

Show comment
Hide comment
@aercanozcan

aercanozcan Jul 30, 2015

"grasped your breast issue" :)
Is there a way to do distinct select in rushorm?

aercanozcan commented Jul 30, 2015

"grasped your breast issue" :)
Is there a way to do distinct select in rushorm?

@Stuart-campbell

This comment has been minimized.

Show comment
Hide comment
@Stuart-campbell

Stuart-campbell Aug 2, 2015

Owner

I have finally got to the bust of your issue.

I will push a new release out later today.

Thanks for you patience.

Owner

Stuart-campbell commented Aug 2, 2015

I have finally got to the bust of your issue.

I will push a new release out later today.

Thanks for you patience.

@Stuart-campbell

This comment has been minimized.

Show comment
Hide comment
@Stuart-campbell

Stuart-campbell Aug 2, 2015

Owner

This should now be resolved in version 1.1.8.

Let me know if its not. If it is fixed can you close this issue please.

Thanks

Owner

Stuart-campbell commented Aug 2, 2015

This should now be resolved in version 1.1.8.

Let me know if its not. If it is fixed can you close this issue please.

Thanks

gcalaprice added a commit to gcalaprice/RushOrm that referenced this issue Oct 29, 2015

Merge branch 'master' of https://github.com/Stuart-campbell/RushOrm
# By Stuart Campbell
# Via Stuart Campbell
* 'master' of https://github.com/Stuart-campbell/RushOrm:
  Updated version number
  Updated rusher version added tests for bug 78
  Updated version number
  Stuart-campbell#73
  Updated version number
  Fixed Stuart-campbell#29
  Updated unit test for Stuart-campbell#29 to now fail. Fix soon.
  Updated version number
  RushCore updated v1.1.11
  Return rows from a child table that aren't connected to a parent? #61

Conflicts:
	RushORM/.idea/misc.xml
	RushORM/rushandroid/src/main/java/co/uk/rushorm/android/AndroidRushConfig.java
	pom.xml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment