Spring + JPA:不从数据库中获取对象

时间:2014-12-07 21:03:07

标签: java mysql spring jpa eclipselink

我正在实施在线商店。我有以下用于保存订单的代码:

@Service
@Transactional
public class OrderServiceImpl extends GenericServiceImpl<Order, Integer> implements OrderService {

    @Inject
    private ItemRepository itemRepository;

    @Override
    public void saveOrder(Order order) {
        this.updateItemsAccordingToOrderedQuantities(order);
        repository.save(order);
    }

    private void updateItemsAccordingToOrderedQuantities(Order order) {
        List<OrderedItem> orderedItems = order.getOrderedItems();
        for (OrderedItem orderedItem : orderedItems) {
            // fetch from database
            Item item = itemRepository.findOne(orderedItem.getItem().getId()); 

            item.reduceWeightInColdStoreBy(orderedItem.getWeight());
            itemRepository.update(item);
        }
    }
}

在实际保存订单之前,我更新了每件商品的“重量”属性(一些数量与此订单一起销售,因此剩下的更少)。

OrderedItem个对象保留对Item的引用,但我想从数据库中获取新的Item(另外检查是否有足够的销售,以防Item数据库中的表已更改,用户提交订单之前UI未更新)。我为此目的而调用的findOne方法实现如下:

@Repository
public class GenericRepositoryImpl<T, ID extends Serializable> implements GenericRepository<T, ID> {
    @PersistenceContext
    EntityManager em;

    protected Class<T> entityClass;

    public GenericRepositoryImpl(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    @Override
    public T findOne(ID id) {
        return em.find(entityClass, id);
    }
}

在调用item不是null之后,但是没有从数据库中获取它:我打开了EclipseLink日志,处于“FINEST”级别,并且没有SELECT查询。

我认为这是因为EclipseLink在其持久化上下文中有item,所以它不执行查询。所以我尝试在em.clear()方法实现中return之前添加findOne,但它没有帮助。

如何从数据库中获取新的item

提前谢谢。

P.S。我已尝试在findOne方法中明确查询,如下所示:

    @Override
    public T findOne(ID id) {
        T result = null;
        try {
            TypedQuery<T> query = em.createQuery("SELECT e FROM " + entityClass.getName() + " e", entityClass);
            result = query.getSingleResult();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return result;
    }

这样我得到了例外:java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: ftcApp.model.Order@cf616dce。我不明白为什么,因为我没有做persist

1 个答案:

答案 0 :(得分:2)

find方法将返回持久化上下文中存在的副本,而不是第二次查询数据库。您可以调用实体管理器的refresh方法,以确保持久化上下文中的副本具有数据库中的最新值: