realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.45k stars 1.75k forks source link

Inheritance / Polymorphism #761

Open cmelchior opened 9 years ago

cmelchior commented 9 years ago

A highly request feature is polymorphism. Mostly for use in ListAdapters, but a lot of other scenarios exists.

We need support for the following:

Example

public abstract Animal extends RealmObject {
  private String name;
}

public class Dog extends Animal {
  private boolean willPlayCatch;
}

public class Spider extends Animal {
  private boolean isScary;
}

// Following should be possible
RealmResults<Animal> animals = realm.where(Animal.class).equalsTo("name","Foo").findAll();
String name = animals.get(0).getName();

RealmResults<Dog> dogs = realm.where(Dog.class).equalsTo("name","Foo").and().equalsTo("willPlayCatch", true).findAll();
String name = dogs.get(0).getName();
T-Spoon commented 9 years ago

Any estimate on a time frame for this? I'm hoping to use Realm in an upcoming project, but without support for Model inheritance I'll have to hold off on trying it out.

Looking forward to where you guys take this project though!

cmelchior commented 9 years ago

Hi @T-Spoon We have a couple of other major features we would like to look at first, so we don't have a timeframe yet, sorry. If inheritance is a dealbreaker for you, you should probably not use us this time around. But we do hope you will come back :)

carotorrehdz commented 9 years ago

:+1:

msegers commented 9 years ago

Still no estimates? Going to write a lot of duplicate code since I want to use Realm anyways. Works fine in swift already. Monitoring this.

cmelchior commented 9 years ago

Unfortunately not. The support for this in Objective C and Swift is actually just sharing fields. It is not proper polymorphism. This is good enough for some use cases, but we feel that without being able to query on abstract super classes it will be less useful on Android. Right now we are focusing on migrations, null support and async querying, but hopefully we will be able to tackle this afterwards.

nolanamy commented 8 years ago

@cmelchior So is there any way to share fields on Android? We have 5 models that all share the same synchronization-related fields and code. We use inheritance in our current SQLite models; if we switch to Realm, will we have to duplicate the synchronization fields across each of the 5 model classes?

As a workaround, I'm thinking about having those classes implement an interface with getters and setters for the shared fields, which at least let me share the synchronization code... is there a better way?

AliSoftware commented 8 years ago

While waiting for this inheritance feature to be available, is there any workaround, like a good practice to design our RLMObjects and model to make such use cases possible?

My need is with a typical object model having, say, Animals objets, subclassed as Dogs and Cats, and I want sometimes to fetch all the Animals (to display in a List only common properties of those animals like their name), and sometimes (e.g. when I tap on an item in the list to show the details) to access properties of the specific class Dog or Cat.

Given that I can't use inheritance to represent that in Realm yet, how would you guys represent your data model instead to make this use-case possible? Adding a relationship from the Dog and Cat RLMObjects to the Animal RLMObject (composition instead of inheritance) maybe?

emanuelez commented 8 years ago

The current solution is to use composition instead of inheritance. There are lots of good argument about it (Gang of Four and Joshua Bloch to mention some prestigious supporters of this approach).

On the other hand we are considering to allow inheritance, but it would not allow queries. For example: Animal which is extended both by Dog, Cat and Duck. You would not be able to query Animals with for legs and have all Dogs and Cats, but not Ducks. We feel this would be a very crippling behavior but are eager to listen to more opinions.

nolanamy commented 8 years ago

@emanuelez Is @AliSoftware's composition-over-inheritance example what you have in mind?

rovkinmax commented 8 years ago

See other model: Im have base object

public abstract class BaseObject {
    private String guid;

    private Map<String, String> name;

    private List<String> tags;

    private double latitude;

    private double longitude;

    private LatLng position;

    @Nullable
    public String getName(String locale) {
        if (name != null) {
            return name.get(locale);
        }
        return null;
    }

    public String getName() {
        return getName(getDefaultLocale());
    }

}

and some other child

public class City extends BaseObject {

    int version;

    boolean current = false;
}
public class Station extends BaseObject {

    Map<String, String> next;

    List<String> routes;

    private List<String> bus;
    private List<String> shuttle;
    private List<String> tram;
    private List<String> troll;
}
public class RoutePoint extends BaseObject {
    int direction;
    String routeGuid;
}

and few other BaseObject contains also equals and hashCode methods How much do I need to copy paste the code and how much it will generate errors?

StErMi commented 8 years ago

Hi, is there any update about this issue?

cmelchior commented 8 years ago

Hi @StErMi We are currently focusing on finishing other features, and we cannot move forward with this until we made changes to the underlying storage engine as it must support querying across abstract types. At this time I am afraid I don't have any timeline.

srikalyan commented 8 years ago

@cmelchior, I can help you guys building this feature but I need little help from you guys in order to get starting so if you can guide me with the kick off process that would be great.

claudioredi commented 8 years ago

I appreciate your hard work on this excellent piece of software but it's a big pain in the ass not being able to use inheritance as we do in swift. I have a big model in swift full of inheritance that I have to implement in Android and now I realize this is not allowed...I never imagined such a restriction could exist on a object oriented language component.

IMO this is a very important thing but this ticket was opened for almost a year without any estimated timeline so I assume the solution is not near :)

cmelchior commented 8 years ago

Unfortunately we don't have a timeline yet. We have a long list of features we would like to do, and we are continuously evaluating the order we do them in, so feedback such as yours is much appreciated.

Note that Swift offers inheritance but not polymorphism, which we think would be the expectation for any Java developer for this feature. So for now we recommend using composition instead of inheritance.

cmelchior commented 8 years ago

@srikalyan Sorry for the late reply. Thank you for your offer, but this feature unfortunately require changes to the underlying core engine (all issues marked "waiting-for-core" does that), but if you find any issues without that label, we would love to start a discussion on them if you want to help.

mlusas commented 8 years ago

@cmelchior Just echoing the desire to have polymorphic relationships supported in Realm. Also, some polymorphic solutions seem to be Integer focused; it would be good to have something that supports Binary and String/Hex as well.

Until Realm releases polymorphic support, we're building workarounds at the cost of performance, code efficiency, and model simplicity.

nomisRev commented 8 years ago

IMO this is a very important thing but this ticket was opened for almost a year without any estimated timeline so I assume the solution is not near :)

I've used Realm for quite a few projects. And having inheritance would save me a lot of trouble. Like someone said before, this ticket was opened a year ago. Realm is my fav library out their for database related stuff in Android. And I hope this feature will be added soon, I think Realm could be a big player in how DB related things get handled in Android. It is great as it is, but missing inheritance in a OOPL like java I think it is a major let down for a lot of people.

I assume there is still no estimated timeline?

Keep up the good work though!

rpip commented 8 years ago

:+1:

savekirk commented 8 years ago

+1

borwoj commented 8 years ago

+1 Hopefully this feature is still on the table

dbauduin commented 8 years ago

+1000

wzieba commented 8 years ago

+1! :)

monossido commented 8 years ago

+1 plz

eyecreate commented 8 years ago

+1

yosrah commented 8 years ago

+1

quangson91 commented 8 years ago

+1

mformetal commented 8 years ago

+1

kmahmood74 commented 8 years ago

+1

milosgh commented 8 years ago

+1

atomontage04 commented 8 years ago

Yeah, we're all waiting! Its a very cool DB and we all want INHERITANCE! :D

joaoBeno commented 8 years ago

@emanuelez and @cmelchior I think this proposed approach is acceptable, since the main drawback of not having this is having to repeat a lot of code for objects that share the same behavior. It should be noted on queries that we can't query objects based on a common ancestor, but we should be able to make joint queries (Like: find Dog and Cat where color is black)... On the future, if the demand for ancestor querying grows, then we can think on some way to create a relation between the parent object and it's siblings to allow the query mentioned by Emanuele...

wpx121314 commented 8 years ago

+1 wait for

rodrigophn7 commented 8 years ago

+1 waiting...

chmoder commented 8 years ago

+1

samyakjain commented 8 years ago

+1

leasual commented 8 years ago

+1

VenomVendor commented 8 years ago

Tracking

bhavyakilari commented 8 years ago

+1

qcawsome commented 8 years ago

+1

juanpinto commented 8 years ago

+1

antonshkurenko commented 8 years ago

One year passed away

barats commented 8 years ago

@cmelchior It's been a year and more, still have NO answer for this?

bmunkholm commented 8 years ago

Wauu - yeah time flies quickly. We would really love to tackle this very soon. During the past year we have closed about 900 issues. This hasn't been one of them since we have always prioritized supporting/helping developers and fixing bugs as 1. priority. Besides that our priority is to fix things that doesn't have any workarounds. We have also gone completely transparent with our issue mgmt and priorities, and you can see a more detailed priority list if you view the issues in waffle.io. Our "S:P1 backlog" list will be tackled first and we will make a 1.0 release. After that we expect this to be among the top 3 features to support. This doesn't give you a date, but we really can't predict it - it depends on the future support load. But I hope it gives at least some insight into what we are thinking.

Drakuwa commented 8 years ago

Oh come on people, do not just comment "+1", I know my comment also has no point, but, you could all just subscribe to the thread and wait for an actual valid response from someone from the team. This way you're not just flooding the issue with unnecessary entries...

lectricas commented 8 years ago

that was the most simple way to show that we are all waiting for this feature.

beeender commented 8 years ago

Comments from #2643 RealmObject should also be able to extend other non-RealmObject/abstract object.

luisribeiro commented 8 years ago

Hi there. Do you know when we will be able to extend a class that extends RealmObject or implements RealmModel?

NitroG42 commented 8 years ago

Hi, I want to try composition over inheritance for now. Let's say we do what @emanuelez suggested :

class Animal {
int numberOfLegs 
String name
}

and

class Dog  { 
Int furSize
Animal animal
}
class Duck  { 
Int featherSize
Animal animal
}

Now if I query for all Animal.class, I will get all of them (that is awesome btw) BUT, for a given Animal, I can't get the related Dog or Duck (at least i don't know how !). Do you have any suggestion @emanuelez ?

I though about doing something like query all child class like Dog, Duck, and group them in a list of the same interface (AnimalInterface for example), that would return common data like title, etc... all instead of querying animal.

emanuelez commented 8 years ago

@NitroG42 If you add a unique id field to the animal class, then you can query for it for all you dogs and ducks. For a cleaner approach you will have to wait for backlinks (https://github.com/realm/realm-java/issues/607)