Java – JPA inheritance is not dry
I have inherited the job, but it's not very dry I have to repeat the coding for each new bolt type It's best to show my course and explain it further
Parent of my boltspec (dimensions related to fasteners)
@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;
And my 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",HEX_BOLT("HEX BOLT",HEAVY_HEX_BOLT("HEAVY HEX BOLT",FLAT_COUNTERSUNK_HEAD_CAP_SCREW("FLAT COUNTERSUNK HEAD CAP SCREW",EnumHeadType.CONE);
Then I must have duplicate classes, i.e. hexcapscrew, heavyhexcapscrew, etc. and hexcapscrew spec, heavyhexcapscrew spec, etc., even if they have similar boltscpec attributes (not numeric values)
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; ...
This specification is different
@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; ...
Here are some examples of import SQL data
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','4.35') values ('3/8','0.375','HEAVY_HEX_CAP_SCREW','0.669') insert into BoltSpecs (basic_size,cone_angle) values ('2-3/4','FLAT_COUNTERSUNK_HEAD_CAP_SCREW','39.77')
I have a drop-down menu at the front end. The user selects the bolt type and needs to use the applicable bolt specification I don't want to modify my import Check and place the bolt head type I risk calling hee hex bolt Is there any way to do multiple discriminatorvalues? Like:
@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); } }
Or how can I Ping enumheadtype as the authentication value? Bolts with similar heads (enumheadtype.cyl, hex and cone) have similar specifications
Solution
I can implement the solution using @ 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','HEX_BOLT','HEAVY_HEX_BOLT') then 'HEX' when boltType in ('FLAT_COUNTERSUNK_HEAD_CAP_SCREW') then 'CONE' end") public abstract class BoltSpec implements Serializable {