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

我正在实施一个在线商店。 我有以下代码来保存订单:

@Service @Transactional public class OrderServiceImpl extends GenericServiceImpl implements OrderService { @Inject private ItemRepository itemRepository; @Override public void saveOrder(Order order) { this.updateItemsAccordingToOrderedQuantities(order); repository.save(order); } private void updateItemsAccordingToOrderedQuantities(Order order) { List 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 implements GenericRepository { @PersistenceContext EntityManager em; protected Class entityClass; public GenericRepositoryImpl(Class entityClass) { this.entityClass = entityClass; } @Override public T findOne(ID id) { return em.find(entityClass, id); } } 

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

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

我如何从数据库中获取新鲜item

先谢谢你。

PS我已经尝试在我的findOne方法中明确查询,如下所示:

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

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

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