JPA找不到新创建的对象

时间:2018-04-10 14:54:01

标签: java jpa glassfish eclipselink

我在JPA中持久保存新对象,然后想要异步索引它。因此,我创建对象,持久化,刷新EntityManager,获取新的id,然后调用异步方法以使索引运行。唉 - 异步方法无法从数据库中检索对象。

存储代码:

em().persist(theDataset);        
// updates....        
theDataset = ctxt.em().merge(theDataset); // store last updates
ctxt.em().flush();
logger.info( "New dataset id is: " + theDataset.getId() ); // logs a valid id
indexSvc.asyncIndexDataset(theDataset.getId(), true)

检索代码:

@Asynchronous
public Future<String> asyncIndexDataset(long datasetId, boolean doNormalSolrDocCleanUp) {
    Dataset toIndex = em.find(Dataset.class, datasetId);
    if ( toIndex == null ) {
        logger.log(Level.WARNING, "Cannot find dataset with id {0}", datasetId);
        return new AsyncResult<>(null);
    } else {
        return indexDataset(toIndex, doNormalSolrDocCleanUp);
    }
}

结果日志:

[2018-04-10T17:41:39.275+0300] [glassfish 4.1] [INFO] [] [...] [tid: _ThreadID=30 _ThreadName=http-listener-1(4)] [timeMillis: 1523371299275] [levelValue: 800] [[
  New dataset id is: 20]]

[2018-04-10T17:41:39.305+0300] [glassfish 4.1] [WARNING] [] [...] [tid: _ThreadID=175 _ThreadName=__ejb-thread-pool10] [timeMillis: 1523371299305] [levelValue: 900] [[
  Cannot find dataset with id 20]]

我做错了什么?

THX

1 个答案:

答案 0 :(得分:1)

刷新实体管理器是不够的。这意味着实体管理器中记录的所有更改都将发送到数据库。 尽管如此,并不意味着其他读者可以阅读这些变化。这取决于数据库的隔离级别。

我认为你的问题是,读者(另一个线程中的索引服务)会去DB读取新持久化的实体,但是原始事务(你持有实体)还没有完成,因此读者找不到它。

我说先让我们完成你的交易,然后尝试对其进行索引,如果只是简单地将持久化对象传递给索引服务,那就更好了(考虑到不会发生任何变化)数据库方面的实体)。