从事务中的不同实体组读取对象

时间:2014-08-08 11:09:00

标签: google-app-engine jdo

我想做什么:

public void updatePremiumFeatureData(Key userKey, OrderItemsDTO orderItemsDTO) throws Exception {
        PersistenceManager pm = PMF.get().getPersistenceManager();
        Transaction txn = pm.currentTransaction();

        try {
            txn.begin();

            UserDTO userData = pm.getObjectById(UserDTO.class, userKey);
            PremiumFeatureDataDTO premiumFeatureData = userData.getPremiumFeatureData();

            for (OrderItemDTO orderItemDTO : orderItemsDTO.getItems()) {
                ProductDTO productDTO = pm.getObjectById(ProductDTO.class, orderItemDTO.getProductKey());

                if (productDTO.getType() == ProductType.PREMIUM_TEMPLATES) {
                    int months = getMonthsToIncrement(orderItemDTO, productDTO);

                    premiumFeatureData.incrementPremiumTemplateExpiryDateBy(months);
                }
                ...
            }

            txn.commit();

            cacheService.removeUser(userKey);
        } catch (Exception e) {
            GAELogger.logError(LOG, e);
            throw e;
        } finally {
            if (txn.isActive()) {
                txn.rollback();
            }
            pm.close();
        }
    }

并且在保存的生产中说:

java.lang.IllegalArgumentException: cross-group transaction need to be explicitly specified, see TransactionOptions.Builder.withXG

有:

ProductDTO productDTO = pm.getObjectById(ProductDTO.class, orderItemDTO.getProductKey());

我知道我不能在交易中写多个实体组(除非我打开跨组交易,我不想这样做)

我也尝试过ProductDAO类:

public ProductDTO getProductByKey(Key productKey) throws Exception {
        ProductDTO productDTO = null;

        PersistenceManager pm = PMF.get().getPersistenceManager();

        try {
            productDTO = pm.getObjectById(ProductDTO.class, productKey);
            ...
        } catch (Exception e) {
            GAELogger.logError(LOG, e);
            throw e;
        } finally {
            pm.close();
        }

        return productDTO;
    }

然后:

ProductDTO productDTO = new ProductDAO().getProductByKey(key);

而不是:

ProductDTO productDTO = pm.getObjectById(ProductDTO.class, orderItemDTO.getProductKey());

是否只为读取位工作?即我想在交易中读取实体组而无意写入。这可能吗?

解决方法:

我必须将productDTO加载到地图中,然后在事务中使用map中的数据。类似的东西:

Map<Key, ProductDTO> map = new HashMap<Key, ProductDTO>();
for (OrderItemDTO orderItemDTO : orderItemsDTO.getItems()) {
    ProductDTO productDTO = pm.getObjectById(ProductDTO.class, orderItemDTO.getProductKey());
    map.put(productDTO.getKey(), productDTO);
}

1 个答案:

答案 0 :(得分:0)

datanucleus.singletonPMFForName

Description Whether to only allow a singleton PMF for a particular name 
(the name can be either the name of the PMF in jdoconfig.xml, or the name of the 
persistence-unit). If a subsequent request is made for a PMF with a name that 
already exists then a warning will be logged and the original PMF returned.

根据DataNucleus文档,只有工厂类成为单例。所以我们想要的是为不同的实体使用PersistenceManager的不同实例。