【问题标题】:How to avoid duplicate code due to the impossibility of using use multiple inheritance. Hibernate由于无法使用多重继承,如何避免重复代码。休眠
【发布时间】:2017-08-14 07:39:12
【问题描述】:

我正在开发 Spring - Hibernate 应用程序,我有一个关于如何正确避免重复代码和使用 Hibernate 的问题,因为无法使用多重继承(我通常使用 Python,所以这不是“问题”)。

我的 UML:

http://i.imgur.com/9GD1sjV.png

我的班级,例如,Periodic,Livro 或 Prototexto 的相同扩展了 GenericEntity:

@Entity
@Table(name = "periodico")
public class Periodico extends GenericEntity {

}

我的问题是:¿在这种两个类的情况下实现继承的方法是什么?

目前我正在这样做并且它有效。但是我在每个类中都复制了一些代码(Produçao activa)。

/**
 * Created by hlorenzo on 03/08/2017.
 */
@Entity
@Table(name = "prototexto")
public class Prototexto extends GenericEntity {


    private String titulo;

    /*
     Código alfanumérico composto por nº de clase + tipo (3 iniciais) + nº Id (3 cifras) + data_ano
    */
    @JsonView(JsonViews.DetailedList.class)
    @Column(name = "numerasao")
    private String numerasao;

    /*
     La utilización del prefijo nacimiento es para que funcione con el componente fecha.component.js de forma automática.
     */
    @JsonView(JsonViews.DetailedList.class)
    @Column(name = "publicacion_dia")
    private Integer nacimientoDia;

    @JsonView(JsonViews.DetailedList.class)
    @Column(name = "publicacion_mes")
    private Integer nacimientoMes;

    @JsonView(JsonViews.DetailedList.class)
    @Column(name = "publicacion_ano")
    private Integer nacimientoAno;

    @JsonView(JsonViews.DetailedList.class)
    @Column(name = "primeira_linha")
    private String primeiraLinha;

    @JsonView(JsonViews.DetailedList.class)
    @Column(name = "ultima_linha")
    private String ultimaLinha;

    @JsonView(JsonViews.DetailedList.class)
    @Column(name = "numero_paginas")
    private Long numeroPaginas;

    @JsonView(JsonViews.DetailedList.class)
    @Column(name = "descrisao")
    private String descrisao;

    @JsonView(JsonViews.DetailedList.class)
    @Column(name = "localizasao")
    private String localizasao;

    @Enumerated(value = EnumType.STRING)
    private TipoPrototexto tipo;


    private boolean revisado;

    private boolean concluido;

    @JsonView(JsonViews.DetailedList.class)
    @ManyToOne
    @JoinColumn(name="pais_id")
    private Pais pais;


    @JsonView(JsonViews.DetailedList.class)
    @ManyToOne
    @JoinColumn(name="ciudad_id")
    private Ciudad ciudad;
[...]
}

还有我的 GenericEntity:

@MappedSuperclass
public abstract class GenericEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonView(JsonViews.List.class)
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}

非常感谢。

【问题讨论】:

  • 什么意思? Java 不支持多重继承。
  • 谢谢@SachinSarawgi。我知道,我只是想减少重复代码。也许创建一个界面。我认为重复变量不是实现它的正确方法。所以......如果Java不支持多重继承,我应该复制代码,还是可以使用其他方式。这才是重点。再次感谢您。
  • 没有“正确”的方式,这与 JPA API 无关,它只是将您定义的类保持不变
  • 看看Code Review。这个问题更适合那里。
  • 交叉发布here

标签: java spring hibernate multiple-inheritance


【解决方案1】:

在许多可以使用从多个父类继承的情况下,您应该使用任一接口(如果您需要在子类中编写自己的实现,并且只想声明您与接口兼容)或使用聚合(如果你不需要覆盖任何东西,只是想重用一些代码,聚合通常更灵活)。

因此,您可以扩展 GenericEntity 并聚合 Publicada,而不是扩展 GenericEntity AND Publicada。

如果将其存储到数据库中,ORM 映射器无论如何都会将继承“转换”为聚合,因此如果您首先使用聚合而不是让 hibernate 将继承转换为聚合,那么它对您的大脑来说更容易可以存储到数据库中。

如果你读过设计模式(有很多关于它的书籍,比如“设计模式”第一章 https://www.google.com/?q=head+first+design+patterns+pdf -> 第 13 页或 google 用于聚合继承 Inheritance vs. Aggregationhttps://en.wikipedia.org/wiki/Composition_over_inheritance),你可以了解为什么聚合通常比继承具有许多优势,以及为什么他们决定禁止从 java 中的多个类继承。

【讨论】:

  • 我的问题不是关于如何避免java中的重复代码,而是如何避免使用Hibernate的代码。我知道我可以使用聚合或接口,但是例如,如果我使用聚合,我需要在我的数据库中创建一个新表。与 Paises 或 Ciudades 一样:@JsonView(JsonViews.DetailedList.class) @ManyToOne @JoinColumn(name="pais_id") private Pais pais;非常感谢@flack。
  • 正如我所写,使用 Hibernate 继承确实是可能的,但是它没有任何好处,它只会伤害你的大脑。我不知道您是使用 Code-First 还是 Database-First 方法,但如果您使用 Code-First 方法并让 hibernate 生成您的表,您可以选择 hibernate 应该如何处理继承。您可以选择 hibernate 如何处理继承的两个选项: - 它生成一个大表,其中包含所有存在的所有子类的 1000 个字段中的每一个的所有 1 列和类名的 1 个附加列 - 或者它将继承转换为聚合。
  • 如果你让 hibernate 将继承转换为聚合,它将为每个类生成 1 个表,无论它是否是抽象类。然后,您放入子类的行将在子类表中获得 1 行,在抽象顶级类表中获得 1 行。子类表将聚合顶级类表。所以和自己直接使用聚合完全一样,只是直接使用聚合,还有很多其他的好处,也少了很多麻烦。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
  • 2016-12-13
  • 2020-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多