问题描述
我有一个更新查询:
@Modifying @Transactional @Query("UPDATE ***** SET firstname = :firstname, lastname = :lastname, login = :login, super***** = :super*****, preference***** = :preference*****, address = :address, zipCode = :zipCode, city = :city, country = :country, email = :email, profile = :profile, postLoginUrl = :postLoginUrl WHERE id = :id") public void update(@Param("firstname") String firstname, @Param("lastname") String lastname, @Param("login") String login, @Param("super*****") boolean super*****, @Param("preference*****") boolean preference*****, @Param("address") String address, @Param("zipCode") String zipCode, @Param("city") String city, @Param("country") String country, @Param("email") String email, @Param("profile") String profile, @Param("postLoginUrl") String postLoginUrl, @Param("id") Long id);
我正在尝试在集成测试中使用它:
I'm trying to use it in an integration test:
*****Repository.update("Toto", "LeHeros", *****0.getLogin(), *****0.getSuper*****(), *****0.getPreference*****(), *****0.getAddress(), *****0.getZipCode(), *****0.getCity(), *****0.getCountry(), *****0.getEmail(), *****0.getProfile(), *****0.getPostLoginUrl(), *****0.getId()); ***** loaded***** = *****Repository.findOne(*****0.getId()); assertEquals("Toto", loaded*****.getFirstname()); assertEquals("LeHeros", loaded*****.getLastname());
但是这些字段没有更新并保留它们的初始值,因此测试失败.
But the fields are not updated and retain their initial values, the test thus failing.
我尝试在 findOne 查询之前添加一个刷新:
I tried adding a flush right before the findOne query:
*****Repository.flush();
但失败的断言保持不变.
But the failed assertion remained identical.
在日志中可以看到更新sql语句:
I can see the update sql statement in the log:
update ***** set firstname='Toto', lastname='LeHeros', login='stephane', super_*****=0, preference_*****=0, address=NULL, zip_code=NULL, city=NULL, country=NULL, email='stephane@thalasoft.com', profile=NULL, post_login_url=NULL where id=2839
但日志显示没有可能与查找器相关的 sql:
But the log shows no sql that could relate to the finder:
***** loaded***** = *****Repository.findOne(*****0.getId()); The finder sql statement is not making its way to the database.
是否因为某些缓存原因而被忽略?
Is it ignored for some caching reason ?
如果我随后添加对 findByEmail 和 findByLogin 查找器的调用,如下所示:
If I then add a call to the findByEmail and findByLogin finders as in:
*****Repository.update("Toto", "LeHeros", "qwerty", *****0.getSuper*****(), *****0.getPreference*****(), *****0.getAddress(), *****0.getZipCode(), *****0.getCity(), *****0.getCountry(), *****0.getEmail(), *****0.getProfile(), *****0.getPostLoginUrl(), *****0.getId()); ***** loaded***** = *****Repository.findOne(*****0.getId()); ***** my***** = *****Repository.findByEmail(*****0.getEmail()); ***** an***** = *****Repository.findByLogin("qwerty"); assertEquals("Toto", an*****.getFirstname()); assertEquals("Toto", my*****.getFirstname()); assertEquals("Toto", loaded*****.getFirstname()); assertEquals("LeHeros", loaded*****.getLastname());
然后我可以在日志中看到正在生成的 sql 语句:
then I can see in the log the sql statement being generated:
但是断言:
assertEquals("Toto", my*****.getFirstname());
即使跟踪显示检索到相同的域对象,仍然失败:
still fails even though the trace shows the same domain object was retrieved:
TRACE [BasicExtractor] found [1037] as column [id14_]
另一个 finder 让我感到困惑的另一件事是,它显示了一个限制 2 子句,即使它应该只返回一个 ***** 对象.
One other thing that puzzles me with this other finder is that it shows a limit 2 clause even though it is supposed to return only one ***** object.
我认为返回一个域对象时总会有一个限制 1.这是对 Spring Data 的错误假设吗?
I thought there would always be a limit 1 when returning one domain object. Is this a wrong assumption on Spring Data ?
在 MySQL 客户端中粘贴时,控制台日志中显示的 sql 语句,逻辑工作正常:
When pasting in a MySQL client, the sql statements displayed in the console log, the logic works fine:
mysql> insert into ***** (version, address, city, country, email, firstname, lastname, login, password, -> password_salt, post_login_url, preference_*****, profile, super_*****, zip_code) values (0, -> NULL, NULL, NULL, 'zemail@thalasoft.com039', 'zfirstname039', 'zlastname039', 'zlogin039', -> 'zpassword039', '', NULL, 0, NULL, 1, NULL); Query OK, 1 row affected (0.07 sec) mysql> select * from *****; +------+---------+---------------+--------------+-----------+--------------+---------------+-------------+------------------+---------+----------+------+---------+-------------------------+---------+----------------+ | id | version | firstname | lastname | login | password | password_salt | super_***** | preference_***** | address | zip_code | city | country | email | profile | post_login_url | +------+---------+---------------+--------------+-----------+--------------+---------------+-------------+------------------+---------+----------+------+---------+-------------------------+---------+----------------+ | 1807 | 0 | zfirstname039 | zlastname039 | zlogin039 | zpassword039 | | 1 | 0 | NULL | NULL | NULL | NULL | zemail@thalasoft.com039 | NULL | NULL | +------+---------+---------------+--------------+-----------+--------------+---------------+-------------+------------------+---------+----------+------+---------+-------------------------+---------+----------------+ 1 row in set (0.00 sec) mysql> update ***** set firstname='Toto', lastname='LeHeros', login='qwerty', super_*****=0, preference_*****=0, address=NULL, zip_code=NULL, city=NULL, country=NULL, email='stephane@thalasoft.com', profile=NULL, post_login_url=NULL where id=1807; Query OK, 1 row affected (0.07 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from *****; +------+---------+-----------+----------+--------+--------------+---------------+-------------+------------------+---------+----------+------+---------+------------------------+---------+----------------+ | id | version | firstname | lastname | login | password | password_salt | super_***** | preference_***** | address | zip_code | city | country | email | profile | post_login_url | +------+---------+-----------+----------+--------+--------------+---------------+-------------+------------------+---------+----------+------+---------+------------------------+---------+----------------+ | 1807 | 0 | Toto | LeHeros | qwerty | zpassword039 | | 0 | 0 | NULL | NULL | NULL | NULL | stephane@thalasoft.com | NULL | NULL | +------+---------+-----------+----------+--------+--------------+---------------+-------------+------------------+---------+----------+------+---------+------------------------+---------+----------------+ 1 row in set (0.00 sec) mysql> select *****0_.id as id14_, *****0_.version as version14_, *****0_.address as address14_, *****0_.city as city14_, *****0_.country as country14_, *****0_.email as email14_, *****0_.firstname as firstname14_, *****0_.lastname as lastname14_, *****0_.login as login14_, *****0_.password as password14_, *****0_.password_salt as password11_14_, *****0_.post_login_url as post12_14_, *****0_.preference_***** as preference13_14_, *****0_.profile as profile14_, *****0_.super_***** as super15_14_, *****0_.zip_code as zip16_14_ from ***** *****0_ where *****0_.email='stephane@thalasoft.com' limit 2; +-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+ | id14_ | version14_ | address14_ | city14_ | country14_ | email14_ | firstname14_ | lastname14_ | login14_ | password14_ | password11_14_ | post12_14_ | preference13_14_ | profile14_ | super15_14_ | zip16_14_ | +-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+ | 1807 | 0 | NULL | NULL | NULL | stephane@thalasoft.com | Toto | LeHeros | qwerty | zpassword039 | | NULL | 0 | NULL | 0 | NULL | +-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+ 1 row in set (0.00 sec) mysql> select *****0_.id as id14_, *****0_.version as version14_, *****0_.address as address14_, *****0_.city as city14_, *****0_.country as country14_, *****0_.email as email14_, *****0_.firstname as firstname14_, *****0_.lastname as lastname14_, *****0_.login as login14_, *****0_.password as password14_, *****0_.password_salt as password11_14_, *****0_.post_login_url as post12_14_, *****0_.preference_***** as preference13_14_, *****0_.profile as profile14_, *****0_.super_***** as super15_14_, *****0_.zip_code as zip16_14_ from ***** *****0_ where *****0_.login='qwerty' limit 2; +-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+ | id14_ | version14_ | address14_ | city14_ | country14_ | email14_ | firstname14_ | lastname14_ | login14_ | password14_ | password11_14_ | post12_14_ | preference13_14_ | profile14_ | super15_14_ | zip16_14_ | +-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+ | 1807 | 0 | NULL | NULL | NULL | stephane@thalasoft.com | Toto | LeHeros | qwerty | zpassword039 | | NULL | 0 | NULL | 0 | NULL | +-------+------------+------------+---------+------------+------------------------+--------------+-------------+----------+--------------+----------------+------------+------------------+------------+-------------+-----------+ 1 row in set (0.00 sec)
那么为什么这没有反映在 Java 级别呢?
So why is this not reflected at the Java level ?
推荐答案
EntityManager 默认不会自动刷新更改.您应该在查询语句中使用以下选项:
The EntityManager doesn't flush change automatically by default. You should use the following option with your statement of query:
@Modifying(clearAutomatically = true) @Query("update RssFeedEntry feedEntry set feedEntry.read =:isRead where feedEntry.id =:entryId") void markEntryAsRead(@Param("entryId") Long rssFeedEntryId, @Param("isRead") boolean isRead);