Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 绕过JPA/Hibernate缓存并命中数据库_Java_Database_Hibernate_Caching_Jpa - Fatal编程技术网

Java 绕过JPA/Hibernate缓存并命中数据库

Java 绕过JPA/Hibernate缓存并命中数据库,java,database,hibernate,caching,jpa,Java,Database,Hibernate,Caching,Jpa,一段时间以来,我一直在努力使用JPA(使用Hibernate)绕过缓存并访问数据库 我们正在构建一个框架来接收必须保存的实体,但在某些情况下,我需要检查数据库中的当前数据,以确定要执行哪种更新(这是业务需求) 因此,我有一个由用户更新的传入附加实体,但我需要验证其当前数据库信息,以确定要执行的业务规则(有时在JPA merge()操作之前,有时在JPA merge()操作之后) 我认为它可以工作的唯一方法是使用entity manager工厂创建一个全新的javax.persistence.En

一段时间以来,我一直在努力使用JPA(使用Hibernate)绕过缓存并访问数据库

我们正在构建一个框架来接收必须保存的实体,但在某些情况下,我需要检查数据库中的当前数据,以确定要执行哪种更新(这是业务需求)

因此,我有一个由用户更新的传入附加实体,但我需要验证其当前数据库信息,以确定要执行的业务规则(有时在JPA merge()操作之前,有时在JPA merge()操作之后)

我认为它可以工作的唯一方法是使用entity manager工厂创建一个全新的javax.persistence.EntityManager,并使用这个新的entity manager执行操作,但我遇到了一个并发错误

看(这在DAO中的save()方法中):

但是当我尝试执行find()操作时,我认为JPA将尝试获取当前由currentEntityManager管理的实例,而不是尝试访问数据库

javax.persistence.PersistenceException: org.hibernate.exception.LockAcquisitionException: could not load an entity: [com.company.framework.persistence.model.TestEntity]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1694)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1141)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1068)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:334)
at com.sun.proxy.$Proxy32.find(Unknown Source)
你们能帮帮我吗?这是一个两周的问题。我真的不知道。
非常感谢。

最简单的解决方案是将数据源注入到您的DAO中,就在实体管理器旁边,并创建一个JDBCTemplate:

 @Autowired
 private final DataSource dataSource;

 private final JdbcTemplate jdbcTemplate;

@Override
public void afterPropertiesSet() {
    jdbcTemplate = new JDBCTemplate(dataSource);
}
然后使用jdbcTemplate运行查询,因为这些查询将使用与EntityManager不同的JDBC连接

如果连接绑定到当前线程,则需要在提交给ExecutorService的可调用线程中执行语句。确保对可调用结果调用Future.get方法,以便原始线程等待可调用结果完成


在JavaEE中,您还可以使用@NotSupported事务传播标记Bean方法。这将挂起当前事务并在单独的事务中执行查询。

您是否尝试过创建一个新的entityManager,而不使用代码
currentEntityManager.GetEntityManager()
?您是否使用强制写入作为锁定类型?还是悲观锁?@uaiHebert我使用JPA默认值,对于并发控制,我使用
@Version
字段
currentEntityManager
是一个使用
@PersistenceContext
的注入式DAO实体管理器。您建议我用哪种方式创建实体管理器,它将访问数据库而不是缓存?谢谢您的提示。。。我认为这将起作用,但我真的不想创建一个新的数据源,因为我已经有一个注入的实体管理器。。。我真不敢相信Hibernate/JPA没有给我一个绕过缓存的选项。这是如此普遍的要求。必须有另一种方法lol:)您不必创建另一个数据源。您只能创建一个实体管理器,并将实体管理器工厂配置为也使用它。检查我的更新答案。我找不到此批注。。。我可以在哪个包裹里找到它?在我的DAO中是否有一个简单的方法用@NotSupported注释?查看Adam Bien关于扩展持久性上下文的示例:在您的例子中,您需要调用另一个用此注释标记的会话Bean。
 @Autowired
 private final DataSource dataSource;

 private final JdbcTemplate jdbcTemplate;

@Override
public void afterPropertiesSet() {
    jdbcTemplate = new JDBCTemplate(dataSource);
}