1

In a spring mvc app using hibernate over MySQL, I am encountering problems when I try to create polymorphic subclasses that inherit their id from a BaseEntity. You can see my intended use when you read my AccessLog class below, which has properties of type BaseEntity. The actor_entity and target_entity properties should each be fillable with a variety of different types of entities, such as User, OutsideSystem, Document, etc., each of which inherit from BaseEntity.

How do I set this up in code?

Here is my current java:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    protected Integer id;
    //other stuff
}

@Entity
@Table(name="users")
public class User extends BaseEntity{
    //other stuff
}

@Entity
@Table(name = "accesslogs")
public class AccessLog extends BaseEntity{

    @ManyToOne
    @JoinColumn(name = "actorentity_id")
    private BaseEntity actor_entity;

    @ManyToOne
    @JoinColumn(name = "targetentity_id")
    private BaseEntity target_entity;

    @Column(name="action_code")
    private String action;
}

Here is my current DDL:

CREATE TABLE IF NOT EXISTS baseentity(
  id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
)engine=InnoDB;SHOW WARNINGS;

CREATE TABLE IF NOT EXISTS accesslogs(
  id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  actorentity_id int(11) UNSIGNED NOT NULL,
  targetentity_id int(11) UNSIGNED NOT NULL,
  action_code varchar(100),
  access_date DATETIME
)engine=InnoDB;SHOW WARNINGS;

CREATE TABLE roles (
  id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  role varchar(20) NOT NULL
) ENGINE=InnoDB;

CREATE TABLE users (
  id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  login varchar(20) NOT NULL,
  password varchar(20) NOT NULL
) ENGINE=InnoDB;

CREATE TABLE user_roles (
  user_id int(11) UNSIGNED NOT NULL,
  role_id int(11) UNSIGNED NOT NULL,
  KEY user (user_id),
  KEY role (role_id)
) ENGINE=InnoDB;

1 Answer 1

1

Why do you need BaseEntity annotate with Entity? You don't need to specify @Inheritance(strategy = InheritanceType.JOINED). BaseEntity should have @MappedSuperclass annotation

And you don't need to create baseentity table

Sign up to request clarification or add additional context in comments.

7 Comments

AccessLog requires BaseEntity to have @Entity annotation because the actor_entity and target_entity both are of type BaseEntity. actor_entity might have subtypes User, Document, ExternalSystem, etc. When I try using @MappedSuperClass annotation for BaseEntity, the actor_entity and target_entity properties of AccessLog do not work. How does this change your answer?
If I correctly understand, then you need to assign specific role to User, and have only one entity with list of Roles
If I take that approach, then AccessLog would have to include separate properties for actor_user, actor_document, actor_externalsystem, etc instead of the generic actor_entity property. This would also require multiple redundant columns in the underlying data table. And each of those entity types would need a separate entity with a list of Roles. This would get very complicated. I am trying to use inheritance and polymorphism to avoid the complexity. Also, the User, Document, and ExternalSystem entities need other functionality that they can use in other parts of the app
What is the purpose of AccessLog?
AccessLog is one example of many types of classes that need to track the activities of a variety of other types of classes. We have polymorphism so that we can fit different types of things in a variety of different types of processes. I just don't know how hibernate needs polymorphism to be written in this situation.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.