Entity inheritance JIRA active objects

Mathieu Yargeau
Contributor
March 25, 2017

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?

2 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

4 votes
Answer accepted
crf
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
March 26, 2017

I don't play around with AO very often, but I think you're looking for the @Polymorphic annotation.

crf
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
March 26, 2017
Tags a given entity type as polymorphically abstract. This means that

the 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 to getComputer(). When an entity type is
polymorphic, its subtypes can be used polymorphically as they are in
Person. This is essentially the conceptual analog of an
abstract class when mapped into the database.

Like Nikita Bakanov likes this
Volodymyr Krupach
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 27, 2017

@Chris Fuller, thank you for sharing! I did not know about @Polymorphic annotation. 

Mathieu Yargeau
Contributor
March 27, 2017

@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?

crf
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
March 27, 2017

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:

  • Computer doesn't get its own table
  • Mac and PC get their own tables
  • All the columns defined by Computer are included in the tables for Mac and PC
  • You can't create a "Computer" directly; you have to be explicitly talking about one or the other
  • You can have relationships to "Computer" that don't care whether they are to a Mac or a PC
  • Because the reference can be to either table, no foreign key is used for references of that type

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.

 

 

Like KlausD likes this
1 vote
Volodymyr Krupach
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 25, 2017

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.

TAGS
AUG Leaders

Atlassian Community Events