使用@MappedSuperclass注释的Hibernate实体多态性

时间:2014-07-07 11:28:53

标签: java hibernate jpa orm hibernate-mapping

考虑以下模型:

抽象类 AbstractLog

@MappedSuperclass
public abstract class AbstractLog{

    private Long id;
    private Set<Comment> comments;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "quasar_log_id_seq")
    public Long getId() {
        return id;
    }

    @OrderBy(clause = "created")
    @OneToMany(mappedBy = "abstractLog", fetch = FetchType.LAZY, cascade = { CascadeType.ALL }, orphanRemoval = true)
    public Set<Comment> getComments() {
        return comments;
    }

    // setters
}

审计日志

@Entity
@SequenceGenerator(name = "quasar_log_id_seq", sequenceName = "quasar_log_id_seq")
public class AuditLog extends AbstractLog {

    private Set<AuditLogItem> items;

    @OrderBy(clause = "date")
    @OneToMany(mappedBy = "auditLog")
    public Set<AuditLogItem> getItems() {
        return items;
    }
}

DocumentationLog

@Entity
@SequenceGenerator(name = "quasar_log_id_seq", sequenceName = "quasar_log_id_seq")
public class DocumentationLog extends AbstractLog {

    private Set<DocumentationLogItem> items;

    @OrderBy(clause = "date")
    @OneToMany(mappedBy = "documentationLog")
    public Set<DocumentationLogItem> getItems() {
        return items;
    }

}

注释

@Entity
@SequenceGenerator(name = "quasar_comment_id_seq", sequenceName = "quasar_comment_id_seq", initialValue = 1, allocationSize =1)
@Table(name = "quasar_comment")
public class Comment extends IdentifiableEntity {

    private User user;
    private String comment;
    private AbstractLog abstractLog;

    @Id
    @Override
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "quasar_comment_id_seq")
    public Long getId() {
        return super.getId();
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_user")
    public User getUser() {
        return user;
    }

    @Column(name = "comment", length = 300)
    public String getComment() {
        return comment;
    }


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "audit_log_id", nullable = false)
    public AbstractLog getAbstractLog() {
        return abstractLog;
    }

}

您会注意到,ID序列生成器对于AbstractLog的所有扩展实体都是相同的。

目标是,Comment的所有扩展实体之间共享实体AbstractLog。是否可以使用注释@MappedSuperclass?如果我使用@Inheritance注释,也会创建AbstractLog类,但我不想这样做。目前抛出引用未知实体错误。

1 个答案:

答案 0 :(得分:1)

@MappedSuperclass用于继承属性,但因为它不代表实体,所以你可以使用实体关系,所以你只剩下基本类型,id生成和乐观锁定版本。

如果您不希望基类成为它自己的表(例如,每个子类的表),则可以使用每个具体的表策略。每个实体都有自己的表,继承的属性只是Java的便利,因为它们将在每个SQL表中重复。

所以你可以用@Map替换@MappedSuperclass:

@Inheritance(InheritanceType.TABLE_PER_CLASS)

但根据Java Persistence wiki

  

单表继承是默认值,每个类的表是一个   JPA规范的可选功能,因此并非所有提供商都支持它。

Hibernate支持它,但如果您打算使用其他JPA提供程序,则可能不支持它。