I have an class in my model that will contain a list of components. Those components can be of several types.
public class some_class { private List<Component> components; } public abstract class component { private String id; private String name; ... some other attributes } public class issue extends component { private String issueType; ... some other attributes } public class space extends component { private int number_of_pages; ... some other attributes }
I am translating my model into entities to save them in tables using Active Objects.
@Preload public interface SomeClassEntity extends Entity { @ManyToMany(value = ClassToComponent.class) public ComponentEntity[] getComponents(); } @Preload public interface ComponentEntity extends Entity { @ManyToMany(value = ClassToComponent.class) public SomeClassEntity[] getSomeClass(); } @Preload public interface ClassToComponent extends Entity { public void setClass(SomeClassEntity someClassEntity ); public SomeClassEntity getClass(); public void setComponent(Label label); public ComponentEntity getComponent(ComponentEntity componentEntity); } @Preload public interface IssueEntity extends ComponentEntity { public void setType(String type); public String getType(); } @Preload public interface SpaceEntity extends ComponentEntity { public void setPages(int pages); public int getPages(); }
Now, can I save, using Active Objects, all my components (issues and spaces) in the same table and then use the ClassToComponent to associate the Some_Class with the Component? I'm afraid that the Component table will only have cloumns for the Component attributes and that if I try to save an Issue or a Space, that it will not take into account their specific attributes.
Should my ComponentEntity class have the attrbutes of IssueEntity and SpaceEntity, and delete those classes (but keep them in the model)? How should I proceed for this case?
Community moderators have prevented the ability to post new answers.
I don't play around with AO very often, but I think you're looking for the @Polymorphic
annotation.
Tags a given entity type as polymorphically abstract. This means thatthe given type will not peer to any table, but rather represent
a polymorphic supertype to other entities (entities which extend the
given interface. Unlike conventional inheritence, which also causes
the supertype to not peer to a table, polymorphic type inheritence
allows instances of the subtype to be stored in the database into fields
which are "typed" in ActiveObjects as the supertype. All of this is
really much simpler than it sounds:
public interface Person extends Entity { public Computer getComputer(); public void setComputer(Computer computer); } @Polymorphic public interface Computer extends Entity { public float getSpeed(); public void setSpeed(float speed); } public interface Mac extends Computer {} public interface PC extends Computer {}
In this case,
Computer
does not correspond with any table in
the database. Likewise,Person
has no foreign keys for the
corresponding field togetComputer()
. When an entity type is
polymorphic, its subtypes can be used polymorphically as they are inPerson
. This is essentially the conceptual analog of an
abstract class when mapped into the database.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Chris Fuller, thank you for sharing! I did not know about @Polymorphic
annotation.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Chris Fuller Thank you for your answer, I'll try both methods (@Polymorphic and @Table), I didn't know about either, and see which behaviour works best in our case. The super type Computer will not have its own table, but Mac and PC will, right? And it can by used with the @ManyToMany annotation?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Well, as I say this isn't something I've ever used myself (though I do notice that the LexoRankAO
class in JIRA Agile has a @Polymorphic
supertype called LockEntity
). In any case, my expectation based on the documentation would be:
The main part I don't understand is how queries would work. At the lowest level, it would need to join to both tables and select the correctly typed table's value. I don't know how it does this. Is there an implicit type indicator column? Do the two tables share a common sequence so that a join on an ID is guaranteed to be unambiguous? Is the problem somehow left up to you to solve?
This is the limit of what I actually know about the feature, so I'd suggest creating a few AO classes to play around with and look at the database to confirm the underlying mechanics directly.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You can try putting @Table("TableName") annotation with the same table name for booth entity classes but I am not sure if it works.
Maybe instead you can use one entity and have a flag to distinguish a record type. Or just declare 2 separate entities with separate tables.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.