Spring + JPA:不会从数据库中获取对象 [英] Spring + JPA: object does not get fetched from the database

查看:69
本文介绍了Spring + JPA:不会从数据库中获取对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一家网上商店.我有以下用于保存订单的代码:

I am implementing an online shop. I have the following code for saving an order:

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

在实际保存订单之前,我会更新每件商品的重量"属性(此订单出售了一些数量,因此剩余的更少).

Before actually saving the order I update the "weight" property of each item (some quantity gets sold with this order, so there is less left).

OrderedItem对象保留对Item的引用,但是我想从数据库中获取新鲜的Item(以额外检查是否有足够的商品出售,以防数据库中的Item表被更改并且UI没有不会在用户提交订单之前更新).为此,我要调用的findOne方法实现如下:

OrderedItem objects hold the reference to Item, but I want to fetch the fresh Item from the database (to additionally check there is enough on sale, in case Item table in database changed and UI didn't update before user submitted order). findOne method I am calling for this purpose is implemented as follows:

@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查询.

After the call item is not null, but it is not fetched from the database: I have EclipseLink logging turned on, at "FINEST" level, and there is no SELECT query.

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

I thought that it is because EclipseLink has this item in its persistence context, so it doesn't execute the query. So I've tried adding em.clear() before return in findOne method implementation, but it didn't help.

我实际上如何从数据库中获取新鲜的item?

How do I actually get the fresh item from the database?

谢谢.

P.S.我尝试在我的findOne方法中显式查询,如下所示:

P.S. I've tried querying explicitly in my findOne method, like so:

    @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.

This way I get the exception: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: ftcApp.model.Order@cf616dce. I have no idea why, because I'm not doing persist.

推荐答案

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

The find method will return the copy that exists in the persistence context rather than querying the database a second time. You can call the refresh method of the entity manager in order to ensure the copy in the persistence context has the latest values from the database:

这篇关于Spring + JPA:不会从数据库中获取对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆