Domanda

This is in continuation with this question I asked a yesterday. After going through various resources and consulting people, I was not able to find any JPA annotations supporting API, for mapping units of measurement. So, I decided to go with creating it myself.

Based on various patterns on Observations and Measurements described by Martin Fowler in his book - Analysis Patterns: Reusable Object Models, I tried to create a basic implementation to meet my needs. I've created two entities, Unit and Quantity, as below: -

Unit entity: -

@Entity
@Table(name = "unit")
public class Unit {

    @Id
    @Column(name = "symbol")
    private String symbol;

    @Column(name = "name")
    private String name;

    @Column(name = "multiplier")
    private Number multiplier;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "symbol")
    private Unit baseUnit;

    public Unit() {

    }

    public Unit(String symbol, String name, Number multiplier, Unit baseUnit) {
        this.symbol = symbol;
        this.name = name;
        this.multiplier = multiplier;
        this.baseUnit = baseUnit;
    }

        /** Getters and Setters **/
}

Quantity Entity: -

@Entity
@Table(name = "quantity")
public class Quantity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int quantityId;

    private Number amount;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "unit")
    private Unit unit;

    public Quantity() {

    }

    public Quantity(Number amount, Unit unit) {
        this.amount = amount;
        this.unit = unit;
    }

    /** Getters and Setters **/
}

And in Item entity, I'm having a reference of Quantity entity, to represent my unitOfIssue and unitOfPurchase. And then, wherever I've to deal with some quantity, I'll have this Quantity reference.

Now, here's the problem I'm facing now. Since Quantity class here will be an entity. So, we have to map it to a DB Table. So, the caveat here is, everytime I want to add some quantity, or update the quantity, an entry will go in the Quantity table first, and then it will be updated in the Item table. I think, the problem is pretty clear. We would have huge entry in the Quantity table, which clearly shows a bad design.

Can someone give an insight on the approach and what options I've while I implement this pattern in JPA? And how can I solve the problem?

È stato utile?

Soluzione

I would recommend this instead. Since units of measure are unlikely to change often, it is worth building them into the code. That way you can meaningfully use the values in the program itself.

It also makes the database more cohesive if it will ever be used anywhere else. You can also extend Quantity to be things LinearQuantity, ArealQuantity, VolumetricQuantity (etc.) to make sure someone isn't trying to buy 30 feet of oil.

@Embeddable
public class Quantity{

   public enum Unit {FEET,METERS,INCHES,MM}

   @Enumerated( value = EnumType.STRING)
   private Unit unit;

   private Number amount;

   public Quantity() {

   }
}


@Entity
Public Class PurchaseOrder
{
    @Embedded
    @AttributeOverrides({
      @AttributeOverride(name="unit", column=@Column(name="UNIT")),
      @AttributeOverride(name="amount", column=@Column(name="AMOUNT"))
    })
    private Quantity quantity;
    ....

}

Altri suggerimenti

  • You need a master table of units which will have all the units as they are fixed so you can create simple script to populate it.
  • For Quantity I will not recommened a seperate entity it can be property to transaction table which can simply establish relation between Item its quantity and unit and you can do that with @OneToOne with Unit Entity.

Here is the sample example

@Entity
Public Class PurchaseOrder
{
@OneToOne
private Unit unitOfPurchase;
@OneToOne
    private Unit unitOfIsuse;

-- Quanity number here ---
}

You should use Cascade very carefully for master tables.

Check out this JPA library for the popular JScience project: JScience-JPA

Based on similar support for Java Monetary types (JSR 354) we also plan to add something similar for JSR 363

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top