1

ProductPriceの 1 つを作成して削除したいのですが、更新は正常に機能していますが、他では例外が発生します

製品クラス

public class Product extends GenericEntity {
    @OneToMany(fetch=FetchType.EAGER, mappedBy = "product", targetEntity = ProductPrice.class, cascade = {CascadeType.ALL}, orphanRemoval=true)
    @Fetch(FetchMode.SUBSELECT)    
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="ncStandardElements")
    private List<ProductPrice> productPrices = new ArrayList<ProductPrice>();

    @OneToMany(fetch=FetchType.EAGER, mappedBy = "product", targetEntity = ProductPrice.class)
    @Fetch(FetchMode.SUBSELECT)    
    @MapKeyJoinColumn(name="CURRENCY_ID")
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region="ncStandardElements")
    private Map<Currency, ProductPrice> productPriceMap = new HashMap<Currency, ProductPrice>();
}

製品価格クラス

public class ProductPrice extends GenericEntitySimple {

    @ManyToOne(targetEntity = Product.class, optional=false)
    @JoinColumn(name = "PRODUCT_ID", referencedColumnName = "ID")
    private Product product;
}




public void removeProductPrice(ProductPrice price){
    Product p = price.getProduct();
    //Map<Currency, ProductPrice> productPriceMap = p.getProductPriceMap();
    //productPriceMap.remove(price);

    List<ProductPrice> prices = p.getProductPrices();
    prices.remove(price);
    p.setProductPrices(prices);
    productDao.merge(p);
}

価格が同じセッションで作成された場合、削除操作は成功しますが、現在のセッションの前に価格が作成された場合、次のエラーがスローされます。

Jun 13, 2013 3:26:29 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet appServlet threw exception
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.netasoft.commerce.framework.catalog.model.ProductPrice#220]
    at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:435)
    at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:233)
    at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:285)
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090)

MapKeyJoinColumn を完全に取得できず、この状況に関するドキュメントが見つかりません。マップ リストのキャッシュがこのエラーの原因だと思います。十分に準備されたドキュメントの提案も承認されます。

4

2 に答える 2

0

私が見つけた最後の解決策は次のとおりです。

本当の問題は、同じオブジェクトが 2 つの異なるリスト キャッシュにあることです。したがって、それらのいずれかを変更すると、選択した FetchType メソッドに従ってエラーが発生します。

FetchTypes をFetchType.EagerFetchType.SUBSELECT、およびCacheConcurrencyStrategy.READ_WRITEとして定義すると、キャッシュの両側のオブジェクトを変更することで簡単にクラッドできます! つまり、price の 1 つを削除したい場合は、productPriceMap&からも削除する必要がありproductPricesます。そしてmerge product;完成!

    @OneToMany(fetch=FetchType.EAGER, mappedBy = "product", targetEntity = ProductPrice.class, cascade = {CascadeType.ALL}, orphanRemoval=true)
    @Fetch(FetchMode.SUBSELECT)    
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="ncStandardElements")
    private List<ProductPrice> productPrices = new ArrayList<ProductPrice>();

    @OneToMany(fetch=FetchType.EAGER, mappedBy = "product", targetEntity = ProductPrice.class)
    @Fetch(FetchMode.SUBSELECT)    
    @MapKeyJoinColumn(name="CURRENCY_ID")
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="ncStandardElements")
    private Map<Currency, ProductPrice> productPriceMap = new HashMap<Currency, ProductPrice>();

CRUD ON SERVICE

public void removeProductPrice(ProductPrice price){
    Product p = price.getProduct();
    Map<Currency, ProductPrice> productPriceMap = p.getProductPriceMap();
    productPriceMap.remove(price);

    List<ProductPrice> prices = p.getProductPrices();
    prices.remove(price);
    p.setProductPrices(prices);

    p.removeProductPriceMap(price);

    productDao.merge(p);
}

public void saveProductPrice(ProductPrice price, boolean isNew){
    Product p = price.getProduct();
    List<ProductPrice> prices = p.getProductPrices();
    if(isNew ){
        prices.add(price);
    }
    else{
        int i = 0;
        for (ProductPrice tp: prices){
            if (tp.getId() == price.getId()){
                prices.set(i, price);
                break;
            }
            i++;
        }
    }

    p.setProductPrices(prices);
    productDao.merge(p);
}
于 2013-07-10T11:39:52.470 に答える