I've never used JPQL before, and I need to use it to batch update the values in a specific column. The column exists in the table, but the entity class was set up without a variable for it. I can't use the exact data, but the setup would be something like this to give you an idea:
Database Columns
Books:
book_id book_title author_id
Authors:
author_id first_name last_name
JPA Entity Classes
Books:
private Integer bookId;
private String bookTitle;
private EAuthor author;
Authors:
private Integer authorId;
private String firstName;
private String lastName;
In the Books entity class, there's a getter & setter for the author_id, but it calls it from the author entity. My dilemma now is I need to batch update all book_titles with the same author_id and I'm unsure how to write the JPQL query statement to do this. I tried:
String queryUpdate = "UPDATE books b SET b.book_title = :bookTitle"
+ " WHERE b.author = :authorId";
and
String queryUpdate = "UPDATE books b SET b.book_title = :bookTitle"
+ " WHERE b.author.authorId = :authorId";
Both queries said both b.author.authorId and b.author were invalid identifiers. Would it make be possible to write 2 separate queries? 1 query as a select statement where I can use joins and then the 2nd to update the result set of the first query?
JPQL is a poor choice for the job. b.author.authorId
is not allowed, as it would translate to an SQL JOIN
. Neither does JPQL support subqueries in UPDATE
statements. You could map the author_id
to a property in Books
:
@Column(name = "author_id", insertable=false, updatable=false)
private Long authorId;
With the above in place, you could just do:
UPDATE Books b SET b.book_title = :bookTitle WHERE b.authorId = :authorId
but you would have to live with altering your domain model just to acommodate a single case with an UPDATE
query.
You should be able to split the task into two queries like so:
List<Long> ids = em.createQuery("SELECT b.id FROM Books b WHERE b.author.id = :authorId", Long.class)
.setParameter("authorId", authorId)
.getResultList();
em.createQuery("UPDATE Books b SET b.bookTitle = :bookTitle WHERE b.id IN :ids")
.setParameter("ids", ids)
.setParameter("bookTitle", bookTitle)
.executeUpdate();
Or, you could simply update the entities from code:
em.createQuery("SELECT b.id FROM Books b WHERE b.author.id = :authorId", Book.class)
.setParameter("authorId", authorId)
.getResultList()
.forEach(book -> book.setBookTitle(bookTitle));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.