【问题标题】:JPA Inheritance is not DRYJPA 继承不是 DRY
【发布时间】:2016-04-12 10:36:06
【问题描述】:

我有继承工作,但它不是很干。每个新的bolt 类型我都必须重复代码。最好展示我的课程,然后进一步解释

BoltSpec 的父类(与紧固件有关的尺寸)

@Entity
@Table(name="BoltSpecs")
@IdClass(BoltSpecCK.class)
@DiscriminatorColumn(name="boltType" )
public abstract class BoltSpec implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private String size;

    @Id
    @Enumerated(EnumType.STRING)
    private EnumBoltType boltType;

    private BigDecimal basic_major_diameter = BigDecimal.ZERO;

还有我的EnumBoltType

public enum EnumBoltType {
    CYLINDER_HEAD_CAP_SCREW("CYLINDER HEAD CAP SCREW", EnumHeadType.CYL),
    HEX_CAP_SCREW("HEX CAP SCREW", EnumHeadType.HEX),
    HEAVY_HEX_CAP_SCREW("HEAVY HEX CAP SCREW", EnumHeadType.HEX),
    HEX_BOLT("HEX BOLT", EnumHeadType.HEX),
    HEAVY_HEX_BOLT("HEAVY HEX BOLT", EnumHeadType.HEX),
    FLAT_COUNTERSUNK_HEAD_CAP_SCREW("FLAT COUNTERSUNK HEAD CAP SCREW", EnumHeadType.CONE);

然后我必须有重复的类,即HexCapScrewHeavyHexCapScrew 等和HexCapScrewSpecHeavyHexCapScrewSpec 等,即使它们具有相似的BoltSpec 属性(不是数值)

public class HexCapScrew extends Bolt {
    private static final long serialVersionUID = 1L;
    private static HexCapScrewSpec spec;
    public HexCapScrew() {
        super(spec);
    }
}

public class HeavyHexCapScrew extends Bolt {
    private static final long serialVersionUID = 1L;
    private static HeavyHexCapScrewSpec spec;
    public HeavyHexCapScrew () {
        super(spec);
    }
}

...

@Entity
@DiscriminatorValue("HEX_CAP_SCREW")
public class HexCapScrewSpec extends BoltSpec implements Serializable {
    private static final long serialVersionUID = 1L;

    public HexCapScrewSpec() {
        super();
    }

    private BigDecimal flat_diameter = BigDecimal.ZERO;
    ...

@Entity
@DiscriminatorValue("HEAVY_HEX_CAP_SCREW")
public class HeavyHexCapScrewSpec extends BoltSpec implements Serializable {
    private static final long serialVersionUID = 1L;

    public HeavyHexCapScrewSpec() {
        super();
    }

    private BigDecimal flat_diameter = BigDecimal.ZERO;
    ...

这个规格不同

@Entity
@DiscriminatorValue("FLAT_COUNTERSUNK_HEAD_CAP_SCREW")
public class FlatHeadCapScrewSpec extends BoltSpec implements Serializable {
    private static final long serialVersionUID = 1L;

    public FlatHeadCapScrewSpec() {
        super();
    }

    private BigDecimal cone_angle = BigDecimal.ZERO;
    ...

这里是一些示例 import.sql 数据

insert into BoltSpecs (basic_size, basic_major_diameter, boltType, flat_diameter) 
    values ('2-3/4', '2.75',  'HEX_CAP_SCREW',       '3.988')
    values ('3',     '3',     'HEX_CAP_SCREW',       '4.35')
    values ('3/8',   '0.375', 'HEAVY_HEX_CAP_SCREW', '0.669')

insert into BoltSpecs (basic_size, basic_major_diameter, boltType, cone_angle) 
    values ('2-3/4', '2.75',  'FLAT_COUNTERSUNK_HEAD_CAP_SCREW',       '39.77')

我在前端有一个下拉菜单,用户可以在其中选择螺栓类型并需要使用适用的螺栓规格。我不想修改我的 import.sql 并放入螺栓头类型。我冒着将CONE 用于HEX 类型螺栓的风险。有没有办法做多个DiscriminatorValues?喜欢:

@Entity
@DiscriminatorValue("HEX_CAP_SCREW, HEAVY_HEX_CAP_SCREW, HEX_BOLT, HEAVY_HEX_BOLT")
public class BoltSpecHexHead extends BoltSpec implements Serializable {
    private static final long serialVersionUID = 1L;

    public BoltSpecHexHead () {
        super();
    }

    private BigDecimal flat_diameter = BigDecimal.ZERO;

...

public class BoltHexHead extends Bolt {
    private static final long serialVersionUID = 1L;
    private static BoltSpecHexHead spec;
    public BoltSpecHexHead () {
        super(spec);
    }
}

或者我怎样才能将 EnumHeadType ping 为鉴别器值?具有相似头部的螺栓(EnumHeadType.CYL、HEX 和 CONE)之间的规格相似

【问题讨论】:

    标签: java jpa inheritance single-table-inheritance


    【解决方案1】:

    我能够使用@DiscriminatorFormula 实现解决方案

    @Entity
    @Table(name="BoltSpecs")
    @IdClass(BoltSpecCK.class)
    //@DiscriminatorColumn(name="boltType" )
    @DiscriminatorFormula("case when boltType in ('CYLINDER_HEAD_CAP_SCREW') then 'HEX' 
       when boltType in ('HEX_CAP_SCREW','HEAVY_HEX_CAP_SCREW','HEX_BOLT','HEAVY_HEX_BOLT') then 'HEX' 
       when boltType in ('FLAT_COUNTERSUNK_HEAD_CAP_SCREW') then 'CONE' end")
    
    public abstract class BoltSpec implements Serializable {
    

    【讨论】:

      【解决方案2】:

      为什么不能你对所有这些都使用同一个类(比如说Bolt)?它们看起来相似,具有相同的属性,它们的行为会改变吗?如果是这样,那么只需在实例周围使用基于螺栓类型的装饰器。

      【讨论】:

      • 螺栓的规格(螺栓头部的尺寸)因螺栓类型而异。 boltSpec 是 bolt 的一个属性。所以我需要一个 HexHead Bolt、一个 PanHeadBolt、一个 socketCapHeadBolt 等。所以我不知道你真正要问的是什么,但我可以使用鉴别器公式。
      猜你喜欢
      • 2011-08-20
      • 2011-09-04
      • 2014-10-30
      • 1970-01-01
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 2019-01-12
      相关资源
      最近更新 更多