Update&Delete using QueryDSL and SpringDataJPA

Updating entities using spring data JPA
SpringDataJPA has a built-in save method to save and update the entity content. If there is a primary key value, the row information of the corresponding primary key will be updated. On the contrary, a new information will be added, which is similar to the saveOrUpdate method of Hibernate. Let's create a UserController first. The code is as follows:
 

package com.yuqiyu.querydsl.sample.chapter3.controller;

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.yuqiyu.querydsl.sample.chapter3.bean.QUserBean;
import com.yuqiyu.querydsl.sample.chapter3.bean.UserBean;
import com.yuqiyu.querydsl.sample.chapter3.jpa.UserJPA;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;

@RestController
public class UserController
{
    @Autowired
    private UserJPA userJPA;

    //Entity manager
    @Autowired
    private EntityManager entityManager;

    //JPA query factory
    private JPAQueryFactory queryFactory;

    @PostConstruct
    public void initFactory()
    {
        queryFactory = new JPAQueryFactory(entityManager);
        System.out.println("init JPAQueryFactory successfully");
    }
}

The above controller is no different from the basic contents of the controller in Chapter 2. When initializing the bean constructor, instantiate the JPAQueryFactory query factory entity through the EntityManager object to facilitate our next query operation. The QueryDsl form needs to be built on the basis of the JPAQueryFactory object. The entity code updated by SpringDataJPA is as follows:
 

    /**
     * Use Jpa to update member information
     * @param userBean
     */
    @RequestMapping(value = "/updateWithJpa")
    public String updateWithJpa(UserBean userBean)
    {
        //Saving member information is equivalent to SaveOrUpdate in Hibernate
        userJPA.save(userBean);
        return "SUCCESS";
    }

Let's take a look at the log output from the console, as shown in the following code:

Hibernate: 
    select
        userbean0_.t_id as t_id1_0_0_,
        userbean0_.t_address as t_addres2_0_0_,
        userbean0_.t_age as t_age3_0_0_,
        userbean0_.t_name as t_name4_0_0_,
        userbean0_.t_pwd as t_pwd5_0_0_ 
    from
        t_user userbean0_ 
    where
        userbean0_.t_id=?
Hibernate: 
    update
        t_user 
    set
        t_address=?,
        t_age=?,
        t_name=?,
        t_pwd=? 
    where
        t_id=?

It can be seen that SpringDataJPA first went to the database to query the current object. If the comparison found that it was inconsistent with the database and there was a primary key value, the following Update statement was executed. Here, if the queried fields were consistent with the updated content, the following Update statement would not be executed. Let's visit the address just now to see the console output as shown in the following code block:

Hibernate: 
    select
        userbean0_.t_id as t_id1_0_0_,
        userbean0_.t_address as t_addres2_0_0_,
        userbean0_.t_age as t_age3_0_0_,
        userbean0_.t_name as t_name4_0_0_,
        userbean0_.t_pwd as t_pwd5_0_0_ 
    from
        t_user userbean0_ 
    where
        userbean0_.t_id=?

Use querysl to update entities

Let's completely use QueryDsl to update the entity. The code is as follows:

/**
     * Update member information using QueryDsl
     * @param userBean
     */
    @RequestMapping(value = "/updateWithQueryDsl")
    public String updateWithQueryDsl(UserBean userBean)
    {
        //querydsl query entity
        QUserBean _Q_user = QUserBean.userBean;

        queryFactory
                .update(_Q_user)//Update Object
                //Update field list
                .set(_Q_user.name,userBean.getName())
                .set(_Q_user.address,userBean.getAddress())
                .set(_Q_user.age,userBean.getAge())
                .set(_Q_user.pwd,userBean.getPwd())
                //update criteria
                .where(_Q_user.id.eq(userBean.getId()))
                //Execute update
                .execute();
        return "SUCCESS";
    }

In the first step, we first obtained the QUserBean query object, and built the update method processing through the JPAQueryFactory object. The parameter of update is the query entity to be updated. Of course, the update method only supports updating a single query entity.  
Next, we will set the field content to be updated. Here is where we can control as we like. You can set the updated contents of the corresponding fields as to which fields need to be updated.  
After setting the update field, you need to set the update conditions. It's OK not to set them. Of course, this is certainly the same as the native SQL. All the data in the table can be updated without setting conditions.  
The last step is crucial. If the execute method is not called, the update operation will not be performed. Next, restart the project and visit the address: 127.0.0.1:8080 / updatewithquerydsl? Id = 6 & name = changewithquerydsl & age = 24 & address = Jinan, Shandong & PWD = 666666. The output content of the interface is shown in Figure 4 below:
 

javax.persistence.TransactionRequiredException: Executing an update/delete query
    at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:54) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at com.querydsl.jpa.impl.JPAUpdateClause.execute(JPAUpdateClause.java:77) ~[querydsl-jpa-4.1.4.jar:na]
    at com.yuqiyu.querydsl.sample.chapter3.controller.UserController.updateWithQueryDsl(UserController.java:76) ~[classes/:na]
.......

It is found that if you want to execute the update/delete method, there must be a transaction, then we modify the update method, add the transaction annotation @ Transactional, restart the project and access our previous address. The output content of the interface is shown in Figure 5 below:

Hibernate: 
    update
        t_user 
    set
        t_name=?,
        t_address=?,
        t_age=?,
        t_pwd=? 
    where
        t_id=?

Delete entity information using spring data JPA

Let's take a look at how spring data JPA should handle when deleting entity information? The code is as follows:

    /**
     * Use Jpa to delete member information
     * @param userBean
     */
    @RequestMapping(value = "/deleteWithJpa")
    public String deleteWithJpa(UserBean userBean)
    {
        //Deletes the value of the specified primary key
        userJPA.delete(userBean.getId());
        return "SUCCESS";
    }

The SQL output from the console is as follows:

Hibernate: 
    delete 
    from
        t_user 
    where
        t_id=?

Before writing the deletion method, we thought of the need to add transactions when updating entities with QueryDsl. Of course, it is also necessary when deleting, so we should pay attention to it when writing the deletion method

Keywords: Java

Added by mizkie on Fri, 04 Mar 2022 14:30:15 +0200