JPA критерии Updatequery ничего не обновляет - PullRequest
0 голосов
/ 11 ноября 2018

Я не могу получить обновление, которое действительно произойдет с Updatequery. Наличие простого тестового класса:

@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";
}    

и тест вроде:

@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);
    }

}

Это должно быть что-то очень простое, но я не могу видеть, что? Я также попробовал em.flush() во всех мыслимых местах.

Должны ли быть где-нибудь дополнительные commit() или какие-то настройки данных Spring?

Строки вставлены правильно. Я вижу соответствующие строки журнала, например:

TestEntity (super=org.example.spring.entity.updatequery.TestEntity@230a73f2, id = 1, сообщение = не изменено)

Я вижу правильные запросы на обновление и привязки (?):

Hibernate:
обновление
test_entity
набор
сообщение =?
.... org.hibernate.type.descriptor.sql.BasicBinder: 65 - параметр привязки [1] как [VARCHAR] - [ИЗМЕНЕННЫЙ ТЕКСТ!]

НО после обновления я не вижу изменений, но:

TestEntity (super=org.example.spring.entity.updatequery.TestEntity@230a73f2, id = 1, сообщение = не изменено)

Соответствующие детали от pom.xml (запросите больше):

<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>
...

1 Ответ

0 голосов
/ 11 ноября 2018

Весь ваш тест выполняется в одной транзакции, поэтому при первой загрузке сущностей они сохраняются в кеше сеанса.И во второй раз, когда вы загружаете их, они просто снова извлекаются из кеша сеанса: запросы на обновление обходят кеш.

Вам необходимо очистить EntityManager перед повторной загрузкой объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...