Reputation: 12215
I am not able to have update to really happen with Updatequery
. Having a simple test class:
@Entity
@ToString(callSuper = true)
// query just for logging purposes
@NamedQuery(name="TestEntity.findAll", query="SELECT t FROM TestEntity t")
public class TestEntity {
@Id
@GeneratedValue
private Long id;
private String message = "not altered";
}
and a test like:
@Slf4j
@DataJpaTest
@org.springframework.transaction.annotation.Transactional(propagation =
Propagation.NOT_SUPPORTED)
@RunWith(SpringRunner.class)
public class TestEntityUpdateTest {
@PersistenceContext
private EntityManager em;
private void buildTestEntity(int i) {
em.persist(new TestEntity());
}
private void log(Object o) {
log.info("\n{}", o);
}
@Test
@Transactional
public void testUpdate() {
IntStream.range(1, 4).forEach(this::buildTestEntity);
TypedQuery<TestEntity> tq =
em.createNamedQuery("TestEntity.findAll", TestEntity.class);
// log inserted stuff
log.info("\nINSERTED rows");
tq.getResultList().forEach(this::log);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaUpdate<TestEntity> update =
cb.createCriteriaUpdate(TestEntity.class);
Root<TestEntity> from = update.from(TestEntity.class);
update.set(from.get("message"), "ALTERED TEXT!");
int i = em.createQuery(update).executeUpdate();
log.info("\nUPDATED {} rows", i);
// log updated stuff
tq.getResultList().forEach(this::log);
}
}
It must be something very simple but I can not see what? I also tried em.flush()
in every imaginable place.
Should there be some extra commit()
or some Spring data setting somewhere?
Rows are inserted correctly. I can see corresponding log rows, like:
TestEntity(super=org.example.spring.entity.updatequery.TestEntity@230a73f2, id=1, message=not altered)
I can see update queries and bindings correct(?):
Hibernate:
update
test_entity
set
message=?
.... org.hibernate.type.descriptor.sql.BasicBinder:65 - binding parameter [1] as [VARCHAR] - [ALTERED TEXT!]
BUT after update I do not see the change, but:
TestEntity(super=org.example.spring.entity.updatequery.TestEntity@230a73f2, id=1, message=not altered)
Relevant parts from pom.xml
(ask for more):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
...
Upvotes: 0
Views: 1479
Reputation: 691755
All your test happens in a single transaction, so the first time you load the entities, they're stored in the session cache. And the second time you load them, they're just retrieved from the session cache again: update queries bypass the cache.
You need to clear the EntityManager before fetching the entities again.
Upvotes: 4