Hibernate 通过JPA标准/JPQL和JPA缓存的DML操作
JPA 2.1分别使用Hibernate 通过JPA标准/JPQL和JPA缓存的DML操作,hibernate,caching,jpa,eclipselink,criteria,Hibernate,Caching,Jpa,Eclipselink,Criteria,JPA 2.1分别使用CriteriaDelete和CriteriaUpdate通过JPA标准API提供对执行删除/更新DML操作的支持 下面给出一个非常简单的示例,该示例使用CriteriaUpdate(由EclipseLink 2.5.2和/或Hibernate 4.3.6 final提供)对相关数据库执行更新操作 我假设代码片段本身是不言自明的。因此,我对他们保持沉默 在这种情况下,与entityManager.merge(brand)不同,DML操作直接在数据库上执行,因此关联的受管实体
CriteriaDelete
和CriteriaUpdate
通过JPA标准API提供对执行删除/更新DML操作的支持
下面给出一个非常简单的示例,该示例使用CriteriaUpdate
(由EclipseLink 2.5.2和/或Hibernate 4.3.6 final提供)对相关数据库执行更新操作
我假设代码片段本身是不言自明的。因此,我对他们保持沉默
在这种情况下,与entityManager.merge(brand)
不同,DML操作直接在数据库上执行,因此关联的受管实体brand
的状态不会受到影响。相关联的JPA回调,如@PreUpdate
,@PostUpdate
,如果有,将不会触发
数据库状态将不会与持久性提供程序管理的实体同步,即,根据持久性提供程序的不同,关联实体(在本例中为brand
)可能不会反映数据库中的更新值
每次调用此方法时,更新操作将传播到数据库,即使实体品牌
未更改/更新
这与使用entityManager.createNativeQuery(“query”)
方法直接对底层数据库执行本机查询是一样的
是否可以赋予此DML操作与entityManager.merge(brand)相同的效果,以便在执行此类操作后,实体状态与数据库的当前状态同步
完成此更新操作后是否需要执行
entityManager.refresh(实体)
(或其他操作),以将数据库中当前保存的状态反映给实体?DML操作直接针对数据库执行,因此绕过一级缓存
拦截器、事件侦听器和JPA PostUpdate钩子都不会被触发,因为更新不是由Hibernate操作队列机制生成的
查询,而不是本地查询,因此最好在进行此类查询之前手动刷新会话,以确保挂起的更改与数据库同步
更新后,您需要刷新所有当前加载的实体,或逐出所有实体并重新加载它们。使用一些数据库访问GUI工具或SQL终端直接对数据库所做的更改会立即反映在ORM中(Hibernate和EclipseLink)。这些更改在刷新浏览器上的关联网页时立即可见(关于web应用程序)。他们(冬眠和/或日食)是否使用了一些特殊的方法来实现这一点?
public boolean update(byte[] file, Brand brand)
{
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaUpdate<Brand>criteriaUpdate=criteriaBuilder.createCriteriaUpdate(Brand.class);
Root<Brand> root = criteriaUpdate.from(entityManager.getMetamodel().entity(Brand.class));
criteriaUpdate.set(root.get(Brand_.brandName), brand.getBrandName());
criteriaUpdate.set(root.get(Brand_.category), brand.getCategory());
criteriaUpdate.set(root.get(Brand_.brandImage), file);
criteriaUpdate.where(criteriaBuilder.equal(root, brand));
return entityManager.createQuery(criteriaUpdate).executeUpdate()>0;
}
public boolean update(byte[] file, Brand brand)
{
return entityManager.createQuery("UPDATE Brand b SET b.brandName=:brandName, b.category=:category, b.brandImage=:brandImage WHERE b.brandId=:brandId")
.setParameter("brandName", brand.getBrandName())
.setParameter("category", brand.getCategory())
.setParameter("brandImage", file)
.setParameter("brandId", brand.getBrandId())
.executeUpdate()>0;
}