2014-12-07 57 views
1

我正在实施一个在线商店。我有保存命令下面的代码:Spring + JPA:对象不会从数据库中获取

@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); 
    } 
} 

通话完后itemnull,但它不是从数据库中获取:我的EclipseLink日志功能,在“最美好”的水平,并且没有SELECT查询。

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

我该如何从数据库中实际获得新的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: [email protected]。我不知道为什么,因为我没有做persist

+0

使用Spring构建在线商店是个不错的主意。我也想这样做。你能推荐任何有用的资料来源吗? – burseaner 2014-12-16 18:45:17

回答

2

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

+0

刚试过这个。抛出'IllegalArgumentException':“无法刷新不受管理的对象:[email protected]。” – 2014-12-07 21:35:47

+1

你试过em.refresh(em.find(entityClass,id))吗?只有当对象没有从持久化上下文中分离出来时(如果你调用em.clear()),刷新才会起作用。但是,首先执行em.find将为您提供持久性上下文中的对象副本,然后您可以刷新该副本。或者,您可以使用em.merge()重新连接分离的实体。 – djmorton 2014-12-07 21:59:38

+0

它的工作!非常感谢你。 – 2014-12-07 22:24:36