2016-01-07 2 views
4

У меня наследование работает, но это не очень СУХОЙ. Каждый новый тип bolt я должен повторить код. Лучше всего, чтобы показать мои классы затем объяснить дальнейшийJPA Наследование не DRY

Моего родительского класса за 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); 

Я тогда должен иметь повторяющиеся классы, т.е. HexCapScrew, HeavyHexCapScrew и т. д. и HexCapScrewSpec, HeavyHexCapScrewSpec и т. д., хотя они имеют аналогичные 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') 

Я имею в интерфейсе раскрывающийся где пользователь выбирает тип болта и должен использовать его e применимые спецификации болтов. Я не хочу изменять свой import.sql и ставить тип головки болта. Я рискую поставить ставку CONE на болт HEX. Есть ли способ сделать несколько DiscriminatorValue? Как:

@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 в качестве значения дискриминатора? Технические характеристики аналогичны между болтами с головками (аналогичные EnumHeadType.CYL, HEX и КОНУСЕ)

ответ

0

мне удалось добиться решения с помощью @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 { 
0

Почему не может использовать один и тот же класс (давайте скажем, Bolt) для всех этих? Они похожи, они имеют одни и те же свойства, меняется ли их поведение? Если это так, то просто используйте декоратор на основе типа болта вокруг экземпляра.

+0

Характеристики болтов (размеры головки болта) различаются между типами болтов. boltSpec - это свойство болта. Поэтому мне нужен HexHead Bolt, PanHeadBolt, socketCapHeadBolt и т. Д. Поэтому я не знаю, что вы действительно спрашиваете, но у меня все работает с использованием дискриминатора. – jeff

Смежные вопросы