Skip to content
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

Add @Polymorphic [moved] #22

Closed
jyemin opened this issue Apr 25, 2013 · 22 comments
Closed

Add @Polymorphic [moved] #22

jyemin opened this issue Apr 25, 2013 · 22 comments
Milestone

Comments

@jyemin
Copy link
Contributor

jyemin commented Apr 25, 2013

This is Issue 22 moved from a Google Code project.
Added by 2010-03-31T16:32:45.000Z by scotthernandez.
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Enhancement, Priority-Medium, Milestone-Release1.1

Original description

Add support for storing (and searching on) the whole super-class tree and the interfaces implemented 
on any of them. Most likely this will be stored as an array of strings called super-classes 
(including the current class-name).

Something like this should be supported:

@Polymorphic
public class Shape {
}

public class Circle extends Shape {
}

public class Square extends Shape {
}

Datastore ds = ...;
List<Shape> shapes = ds.find(Shape.class).asList()
for(Shape shape : shapes)
  print(shape.getClass().getName());

> Circle
> Square
> Shape
> Circle
> Circle
@marstonstudio
Copy link

We just ran into this limitation which is having an impact on what we can do with Morphia. Also referenced on stack overflow: http://stackoverflow.com/questions/21921442/getting-multiple-types-from-same-morphia-query

Any interest in this now? It looks like this original ticket is from 2010. :(

@evanchooly
Copy link
Member

Interest, yes. The timing is uncertain. Probably post-1.0 at this point. The C# driver has an interesting solution i'll probably steal but it'll take some refactoring first.

@nosachamos
Copy link

This is major for me as well. I'm facing a lot of issues and having to resort to direct driver use to work around these issues as Morphia does not play nicely with polymorphic structures.

Say, if one has class A and B and C that inherit from them it seems natural that A could be annotated with @polymorphic and all instances of A, B and C would then go to the A's collection. For each record, I like the idea of storing an array of class names going up in the type hierarchy for stored objects instead of the fully qualified name for the concrete implementation classes stored. This way one could query for instances of A, B, C or a combination of them and have them properly filtered and casted.

This is a major limitation and a bit discouraging to see it open from 2010... it's been 5 year after all :(

@nosachamos
Copy link

Just as a side not if anyone is interested in a work around, as for the example above instead of querying for
datastore.find(Circle.class)

...I am instead querying for:

datastore.createQuery(Circle.class).disableValidation().filter("className =", Circle.class.getCanonicalName()).asList();

which works well but is a bit ugly. Also I don't know if we add an index to the className field but if we don't then this could make this query very slow for large data sets.

@ivmikhail
Copy link

+1 to issue

3 similar comments
@ondevelop
Copy link

+1 to issue

@Fuzzo
Copy link

Fuzzo commented Jul 17, 2015

+1 to issue

@eugene-ivakhno
Copy link

+1 to issue

@ghost
Copy link

ghost commented Sep 26, 2015

+1

1 similar comment
@naveensky
Copy link

+1

@sgatade
Copy link

sgatade commented Feb 16, 2016

+1 or is this closed i.e. implemented already?

@randm-ch
Copy link

+1

1 similar comment
@aiaizhaoying
Copy link

+1

@evanchooly evanchooly added this to the 2.0 milestone May 25, 2016
@mdoh
Copy link

mdoh commented Jul 15, 2016

any progress about this one?

@webermich
Copy link

I know this ticket is pretty old but I just wanted to provide an alternative.
Have a look at Polymorphia
Among other things Polymorphia adresses the need to persist polymorphic data structures.
It is based on the java mongo driver and adds a codec to support POJOs.
Also generic classes are supported. Polymorphia provides fine grained control over discriminator handling within the mongo database.
Give it a try and let me know, what you think.

@abulvenz
Copy link

abulvenz commented Jun 7, 2018

Any opinions or progress about this issue? Otherwise we can start the 5 year celebration - if it didn't take place already ;-) Thanks @webermich for your effort, but changing the mapping to a different mechanism is not possible for me at the moment.

@evanchooly
Copy link
Member

I actually have this done in my fork that I'm working on. I've replaced the mapping code with the driver's POJO stuff i helped write. It's getting pretty close to done.

@sn0opy
Copy link

sn0opy commented Feb 5, 2019

@evanchooly any update on this?

@TheFlash787
Copy link

+1 🥇

@evanchooly
Copy link
Member

working now in 2.0 though the @Polymorphic annotation isn't necessary.

fwautobuild pushed a commit to fwHub/morphia that referenced this issue Feb 2, 2021
FongoDBCollection.idsIn(DBObject) throws ClassCastException
Check if it's a List or Object array before casting
fwautobuild pushed a commit to fwHub/morphia that referenced this issue Feb 2, 2021
fwautobuild pushed a commit to fwHub/morphia that referenced this issue Feb 2, 2021
@guss77
Copy link

guss77 commented Sep 4, 2023

@evanchooly Can you please explain how this should work in Morphia 2.4.2?

I tried:

// ... Junit setup...

	@Entity("shapes")
	public static class BaseShape {
		@Id
		protected ObjectId id;
		protected int sides;
	}

	@Entity("shapes")
	public static class Circle extends BaseShape {
		{ sides = 0; }
	}

	@Entity("shapes")
	public static class Triangle extends BaseShape {
		{ sides = 3; }
	}
	
	@Test
	void minimalTestCase() {
		log.info("Starting test");
		var ds = datastore();
		ds.getMapper().map(BaseShape.class, Circle.class, Triangle.class);
		ds.save(new Circle());
		ds.save(new Triangle());
		log.info("Trying to find shapes");
		ds.find(BaseShape.class).forEach(s -> {
			log.info("Found: " + s);  // --> nothing was printed from here
		});
		log.info("These were all the shapes");
	}

If I save an instance of BaseShape - then that can be found. If I search for any of the child types, I find only instance of that specific sub-type.

@evanchooly
Copy link
Member

evanchooly commented Sep 4, 2023

You have to enable polymorphic queries. But please open a discussion topic rather than comment on 10 year closed issues so that folks aren't notified unnecessarily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests