【发布时间】:2015-02-05 12:09:43
【问题描述】:
我正在实施一个在线商店。我有以下代码用于保存订单:
@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,但它没有从数据库中获取:我在“FINEST”级别打开了EclipseLink 日志记录,并且没有SELECT 查询。
我认为这是因为 EclipseLink 在其持久性上下文中有这个 item,所以它不执行查询。所以我尝试在findOne方法实现中在return之前添加em.clear(),但没有帮助。
我实际上如何从数据库中获取新的item?
提前谢谢你。
附:我尝试在我的 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。
【问题讨论】:
-
使用 Spring 建立在线商店是个好主意。我也想做。你能推荐任何有用的资源作为它的起点吗?
标签: java mysql spring jpa eclipselink