1

私は休止状態が初めてです。私は Hibernate 4.0、特に JPA アノテーションを使用しています。

Order クラスがあります。注文には、複数の SKU (「SKU」は在庫管理単位です。ウィキペディアを参照してください) と、各 SKU の 1 つ以上を含めることができます。Order クラスと Sku クラスは次のとおりです。関連する sku と一緒に注文を同じテーブルに保持したいのですが、必要に応じて 2 つのテーブルを使用することもできます。HashMap を永続化する方法がわかりません - ランタイム例外がスローされますjavax.persistence.PersistenceException: org.hibernate.exception.DataException: Data truncation: Data too long for column 'skusInOrder' at row 1

[this][2] Stackoverflow の質問を読みました: - 私のシナリオで @Lob アノテーションを使用するというアドバイスは意味がありますか? @Embedded または @Embeddable および/または @ElementCollection を使用する必要がありますか?

package com.newco.drinks.data;

import java.io.Serializable;
import java.math.RoundingMode;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.joda.money.CurrencyUnit;
import org.joda.money.Money;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.SecondaryTable;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

@Entity
@Table(name="Orders")
public class Order implements Serializable {

    private static final long serialVersionUID = 5915005362337363656L;
    private List<Sku> availableSkus;
    private String barId;
    private java.util.Date collectionNotificationTime;
    private CurrencyUnit currencyUnit;
    private String customerId;
    private String orderId;
    private Money orderTotal;
    private String paymentProcessorRef; 
    private Boolean paymentSuccessful;
    private HashMap<Sku, Integer> skusInOrder = new HashMap<Sku, Integer>(); // skuId and quantity thereof
    private java.util.Date timeReceived;

    /**
     * 
     * @param sku
     * @param quantity
     * @throws IllegalArgumentException
     *             if quantity is zero or negative, or if the Order does not
     *             contain the Sku
     * @throws ConcurrentModificationException
     */
    void add(Sku sku, int quantity) throws IllegalArgumentException, ConcurrentModificationException {

        if (quantity <= 0) {
            throw new IllegalArgumentException("Quantity must be greater than zero, but was " + quantity);
        }

        if (skusInOrder.isEmpty() || !skusInOrder.containsKey(sku)) {
            skusInOrder.put(sku, quantity);
        } else {
            if (skusInOrder.containsKey(sku)) {
                int i = skusInOrder.get(sku);
                skusInOrder.put(sku, i + quantity);
            } else {
                throw new IllegalArgumentException("Order " + getOrderId() + " does not contain SKU " + sku.getSkuId());
            }
        }
    }

    private Money calculateOrderTotal() {

        int decimalPlaces = currencyUnit.getDecimalPlaces();
        String zeroString = null;

        switch (decimalPlaces) {
        case 1:
            zeroString = "0.0";
            break;
        case 2:
            zeroString = "0.00";
            break;
        case 3:
            zeroString = "0.000";
            break;
        case 4:
            zeroString = "0.0000";
            break;
        }

        Money total = Money.of(currencyUnit, new Double(zeroString));

        for (Sku sku : skusInOrder.keySet()) {

            int quantity = skusInOrder.get(sku);
            Money totalExTax = sku.getPrice().multipliedBy(quantity, RoundingMode.HALF_UP);

            double taxRate = sku.getTaxRate();
            if (taxRate > 0) {
                Money tax = totalExTax.multipliedBy(taxRate / 100, RoundingMode.HALF_UP);
                total = total.plus(totalExTax.plus(tax));
            } else {
                total = total.plus(totalExTax);
            }
        }

        return total;
    }

    /**
     * 
     * @return a List of Sku objects available to be added to this order.
     *         Different bars will have different Skus available.
     */
    @Transient
    @OneToMany
    public List<Sku> getAvailableSkus() {
        return availableSkus;
    }

    @Column(name="barid", nullable=false)
    public String getBarId() {
        return barId;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "collectionnotificationtime")
    public java.util.Date getCollectionNotificationTime() {
        return collectionNotificationTime;
    }

    @Column(name="currencyunit", nullable=false)
    public CurrencyUnit getCurrencyUnit() {
        return currencyUnit;
    }

    @Column(name="customerid", nullable=false)
    public String getCustomerId() {
        return customerId;
    }

    @Id
    @Column(name="orderid", nullable=false)
    public String getOrderId() {
        return orderId;
    }

    //@Column(name="ordertotal", nullable=false)
    @Transient
    public Money getOrderTotal() {
        return calculateOrderTotal();
    }

    @Column(name="paymentprocessorref", nullable=true)
    public String getPaymentProcessorRef() {
        return paymentProcessorRef;
    }

    @Column(name="paymentsuccess", nullable=true)
    public Boolean getPaymentSuccessful() {
        return paymentSuccessful;
    }

    @Column(name="skusinorder", nullable=false)
    public HashMap<Sku, Integer> getSkusInOrder() {
        return skusInOrder;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "timereceived")
    public java.util.Date getTimeReceived() {
        return timeReceived;
    }

    /**
     * 
     * @param sku
     * @param quantity
     * @throws IllegalArgumentException
     *             if quantity is zero or negative, or if the Sku does not form
     *             part of the Order
     * @throws ConcurrentModificationException
     */
    void remove(Sku sku, int quantity) throws IllegalArgumentException, ConcurrentModificationException {

        if (quantity <= 0) {
            throw new IllegalArgumentException("Quantity to remove must be greater than zero for order " + getOrderId() + ", but was " + quantity);
        }

        if (skusInOrder.isEmpty() || !skusInOrder.containsKey(sku)) {
            throw new IllegalArgumentException("Cannot remove sku " + sku.getSkuId() + " which doesn't form part of order " + getOrderId());
        } else {
            int i = skusInOrder.get(sku);
            if (quantity <= i) { // fine, this is expected
                skusInOrder.put(sku, i - quantity);
            } else if (quantity == i) { //okay, remove that sku altogether as its quantity is now zero
                skusInOrder.remove(sku);
            }
        }
    }

    void setAvailableSkus(List<Sku> availableSkus) {
        this.availableSkus = availableSkus;
    }

    void setBarId(String barId) {
        this.barId = barId;
    }

    void setCollectionNotificationTime(
            java.util.Date collectionNotificationTime) {
        this.collectionNotificationTime = collectionNotificationTime;
    }

    void setCollectionReadySent(java.util.Date collectionReadySent) {
        this.collectionNotificationTime = collectionReadySent;
    }

    void setCurrencyUnit(CurrencyUnit currencyUnit) {
        this.currencyUnit = currencyUnit;
    }

    void setCustomerId(String customerId) {
        this.customerId = customerId;
    }

    void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    void setOrderTotal(){
        orderTotal = calculateOrderTotal();
    }

    void setPaymentProcessorRef(String paymentProcessorRef) {
        this.paymentProcessorRef = paymentProcessorRef;
    }

    void setPaymentSuccessful(Boolean paymentSuccessful) {
        this.paymentSuccessful = paymentSuccessful;
    }
}


package com.newco.drinks.data;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import org.joda.money.CurrencyUnit;
import org.joda.money.Money;

@Entity
@Table( name = "Skus" )
public class Sku implements Serializable{

    private static final long serialVersionUID = 8375466982619713795L;
    private String skuId;
    private String barId;
    private CurrencyUnit currencyUnit;
    private double price;
    private String description;
    private String brand;
    private String skuType;
    private double taxRate;

    protected Sku(){
        // no args constructor for Hibernate use
    }

    public Sku(String skuId, String barId, CurrencyUnit currencyUnit, double price, String description, String brand, String skuType, double tax) {
        setSkuId(skuId);
        setBarId(barId);
        setCurrencyUnit(currencyUnit);
        setPrice(price);
        setDescription(description);
        setBrand(brand);
        setSkuType(skuType);
        setTaxRate(tax);
    }

    @Column(name="barid", nullable=false)
    public String getBarId() {
        return barId;
    }

    @Column(name="brand", nullable=true)
    public String getBrand() {
        return brand;
    }

    @Column(name="currencyunit", nullable=false)
    public CurrencyUnit getCurrencyUnit() {
        return currencyUnit;
    }

    @Column(name="description", nullable=false)
    public String getDescription() {
        return description;
    }

    @Column(name="price", nullable=false)
    public Money getPrice() {
        return Money.of(currencyUnit, price);
    }

    @Id
    @Column(name="skuid", nullable=false)
    public String getSkuId() {
        return skuId;
    }

    @Column(name="skutype", nullable=false)
    public String getSkuType() {
        return skuType;
    }

    @Column(name="taxrate", nullable=false)
    public double getTaxRate() {
        return taxRate;
    }

    void setBarId(String barId) {
        this.barId = barId;
    }

    void setBrand(String brand) {
        this.brand = brand;
    }

    void setCurrencyUnit(CurrencyUnit currencyUnit) {
        this.currencyUnit = currencyUnit;
    }

    void setDescription(String description) {
        this.description = description;
    }

    void setPrice(double price) {
        this.price = price;
    }

    void setSkuId(String skuId) {
        this.skuId = skuId;
    }

    void setSkuType(String skuType) {
        this.skuType = skuType;
    }

    void setTaxRate(double tax) {
        this.taxRate = tax;
    }



}

[2]: hibernate , Integerで HashMap を永続化する方法

4

1 に答える 1

3

最初に、フィールドを(オブジェクトを参照するための具象クラスよりも常にインターフェイスを優先する)Mapではなく、型として定義します。HashMap

次に、最良のオプションは を使用すること@ElementCollectionです。そうすれば、休止状態は (hbm2ddl が有効な場合) 別のテーブルを作成し、そこに結果を入力します。を使用し@Lobても機能しますが、Java の外部 (つまり、コマンドライン mysql ツール) で読み取ると、フィールドは「ブラックボックス」になります。

于 2012-12-28T14:41:01.740 に答える