Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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 spring数据jpa中的复杂快速更新_Java_Hibernate_Jpa_Spring Data Jpa - Fatal编程技术网

Java spring数据jpa中的复杂快速更新

Java spring数据jpa中的复杂快速更新,java,hibernate,jpa,spring-data-jpa,Java,Hibernate,Jpa,Spring Data Jpa,我有一个名为Product的实体。它有几个字段,用户可以任意更新其中的一个或多个字段。对于更新产品s,我知道我可以从数据库中获取持久化产品,并更新它的字段,然后再次保存它,但这会导致真正的性能损失。更好的方法是在ProductRepostory界面中创建自定义更新查询,但在这种情况下,我应该为每个场景编写多个更新函数。我想得到更新字段及其值的映射,并编写一个按比例更新主题的查询 我听说Hibernate能够创建自定义的更新查询并像下面的代码一样执行 @Stateless @LocalBean p

我有一个名为
Product
的实体。它有几个字段,用户可以任意更新其中的一个或多个字段。对于更新
产品
s,我知道我可以从数据库中获取持久化产品,并更新它的字段,然后再次
保存
它,但这会导致真正的性能损失。更好的方法是在
ProductRepostory
界面中创建自定义更新查询,但在这种情况下,我应该为每个场景编写多个更新函数。我想得到更新字段及其值的
映射,并编写一个按比例更新主题的查询

我听说Hibernate能够创建自定义的更新查询并像下面的代码一样执行

@Stateless
@LocalBean
public class OrderManagement {
    @PersistenceContext
    private EntityManager em;

    ...

    public void updateOrder(Double oldAmount, Double newAmount) {
        CriteriaBuilder cb = this.em.getCriteriaBuilder();

        // create update
        CriteriaUpdate<Order> update = cb.
        createCriteriaUpdate(Order.class);

        // set the root class
        Root e = update.from(Order.class);

        // set update and where clause
        update.set("amount", newAmount);
        update.where(cb.greaterThanOrEqualTo(e.get("amount"), oldAmount));

        // perform update
        this.em.createQuery(update).executeUpdate();
    }

} 
@无状态
@本地豆
公共类订单管理{
@持久上下文
私人实体管理者;
...
公共作废更新订单(双倍旧金额,双倍新金额){
CriteriaBuilder cb=this.em.getCriteriaBuilder();
//创建更新
CriteriaUpdate=cb。
createCriteriaUpdate(Order.class);
//设置根类
Root e=update.from(Order.class);
//set update和where子句
update.set(“金额”,newAmount);
更新。其中(cb.greaterThanOrEqualTo(e.get(“金额”),oldAmount));
//执行更新
this.em.createQuery(update.executeUpdate();
}
} 

但我想知道如何在SpringDataJPA环境中使用它,最大的问题是如何获得entityManager实例,下一个问题是将此功能放在哪里最合适
ProductRepostory
接口或某些自定义接口,如果答案是自定义接口,如何注册?

好的,问这个问题的主要原因是一个错误的假设,我认为获取和更新程序中的实体可能会导致性能问题,但正如@jbniset所提到的,通过id获取实体很快,而且Hibernate还处理实体上的持久性更改,不需要手动调用
save


简而言之,提出保存托管实体的新方法是没有帮助的,最好避免手动更新实体,但是如果想要手动扩展Jpa存储库,正如在评论中提到的那样,这里有一些解释。

您可以在上面的链接中找到Spring数据中的自定义存储库。也可以像这样注入Entity manager<代码>@PersistenceContext EntityManager EntityManager1。您不需要再次保存它:Hibernate会为您保存它。2.不,这不会造成任何真正的性能损失。通过ID读取表中的行非常快。你在过早地优化,这是所有邪恶的根源。您的代码将变得更加复杂,对于想象中的性能增益来说,安全性将降低。@JBNizet我必须说我是您的忠实粉丝。你是说每次我更新一个实体的字段时,hibernate会自动将其持久化吗?不调用
保存
?这是默认行为还是必须手动启用?是的,这是默认行为,您无需对此做任何操作。托管实体(即您在事务中持久化的实体,或使用实体管理器、JPQL查询或通过浏览其他托管实体的关联获得的实体)是。。。由JPA管理。将检查它们的状态,如果状态已更改,JPA会在需要时(在提交之前,或在其结果可能受新状态影响的查询之前)将其保存在DB中。