Stuart-campbell / RushOrm

Object-relational mapping for Android
http://www.rushorm.co.uk/
Other
172 stars 19 forks source link

RushORM doesn't have an update function #119

Closed pariola closed 8 years ago

pariola commented 8 years ago

I tried to update using:

new RushSearch().find(Story.class).get(0).setTitle("dfsdfs").build().save();

then the result of that just creates another data in the database

Stuart-campbell commented 8 years ago

Hi,

Can you please share you 'Story' class i'm just interested in what build does.

Thanks

danielkmb2 commented 8 years ago

Hi,

I`m having this same problem. When modifying an object that owns a list of other RushObjects, the old one remains in the DB with this column as null, and a new one is created with the modified object.

Hope i can get some feedback on how to solve this, thanks!

Stuart-campbell commented 8 years ago

Hi,

Would you be able to share your classes and the saving code that causes the problem.

Thanks

danielkmb2 commented 8 years ago

Hello,

I have this two classes:

public class Channel extends RushObject {
    private String name;
    @RushList(classType = Event.class)
    private List<Event> events;

    public void addEvent(Event event) {
        this.events.add(event);
    }

/* Assume getters and setters */
}

public class Event extends RushObject{
    private String name
/* Assume getters and setters */
}

And this is what im testing:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AndroidInitializeConfig config = new AndroidInitializeConfig(getApplicationContext());
        config.addPackage("com.example.danielpadin.rushtest");

        List<Class<? extends Rush>> classes = new ArrayList<>();
        classes.add(Channel.class);
        classes.add(Event.class);
        config.setClasses(classes);
        config.setInitializeListener(new InitializeListener() {
            @Override
            public void initialized(boolean b) {
                RushCore.getInstance().clearDatabase();
                testStuff();
            }
        });

        RushCore.initialize(config);
    }

    void testStuff() {
        List<Event> events = new ArrayList<>();
        events.add(new Event("event1"));

        Channel c = new Channel("channel1", events);
        c.save();

        Channel object = new RushSearch().findSingle(Channel.class);
        Log.i("TEST", "" + object);
        object.addEvent(new Event("added event"));
        object.save();

        Log.i("TEST", "" + new RushSearch().find(Channel.class));
    }

The result of running this are these two log lines:

I/TEST: Channel{name='channel1', events=[Event{name='event1'}]}

I/TEST: [Channel{name='channel1', events=null}, Channel{name='channel1', events=[Event{name='event1'}, Event{name='added event'}]}]

So it seems that i have one channel that lost its list of events, and a new one that has the new data?

Thanks for your attention!

Stuart-campbell commented 8 years ago

Hi,

I coped your code into a unit test, but the test passes both on my local and via travis ci.

Are you able to have a look over the commit above and see where the test differs from yours see if we can pin point the issue.

Thanks

danielkmb2 commented 8 years ago

The test seems to be exactly what im doing, but im not having the same result (?). Testing the same, my RushSearch is finding 2 objects in the database.

With this code:


        List<Channel> channels = new RushSearch().whereEqual("name", "channel1").find(Channel.class);
        Log.i("TEST", "" + channels.size() + ": " + channels);

        List<Event> events = new ArrayList<>();
        events.add(new Event("event1"));

        Channel c = new Channel("channel1", events);
        c.save();

        Channel object = new RushSearch().findSingle(Channel.class);
        Log.i("TEST", "" + object);
        object.addEvent(new Event("added event"));
        object.save();

        List<Channel> channels2 = new RushSearch().whereEqual("name", "channel1").find(Channel.class);
        Log.i("TEST", "" + channels2.size() + ": " + channels2);

This is the output that im getting:

I/TEST: 0: [] I/TEST: Channel{name='channel1', events=[Event{name='event1'}]} I/TEST: 2: [Channel{name='channel1', events=null}, Channel{name='channel1', events=[Event{name='event1'}, Event{name='added event'}]}]

Note that im clearing the database before this operations.

Thanks for your attention!

Stuart-campbell commented 8 years ago

Hi,

Trying to reporduce, not having any luck.

You don't have a "getId()" method by any chance? If not I'm not sure ill be able to give much help without a full project/unit test where it is reproducible.

Thanks

danielkmb2 commented 8 years ago

Hello,

I uploaded the test project here, take a look if you can :)

Tanks!

Stuart-campbell commented 8 years ago

Hi,

The issue is overriding the hash code method. All the ids are stored in a WeakHashMap but as your hash code depends on the array when you update it the HashCode changes. This means that it does not find the old id so thinks it's a new object which is why you are getting two.

To resolve don't bother overriding that method. I am yet to come up with a good way around this issue that would not effect performance.

Hope that helps.

Thanks

danielkmb2 commented 8 years ago

ook! The problem was right there. Thanks a lot for your help!

luisfermp19 commented 7 years ago

Hi!

Have you found the solution for this?