JPA @ Entity не удалось создать после создания? - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть простой метод контроллера, где я создаю новый объект Car, а затем задаю его имя Audi:

@GetMapping(value = "/resource")
public ResponseEntity visit() {
    Car car = carRepo.save(new Car("VolksWagen")); // Car should be managed now?
    car.setName("Audi"); // <-- has no effect on database state

    return ResponseEntity.ok().build();
}

В базе данных он никогда не становится Audi, но остается VolksWagen.

Почему это происходит? Разве только что созданный Car должен находиться в управляемом состоянии для постоянства контекста?

Примечание. Работает, если добавить аннотацию @Transactional. Я думал, что будет достаточно, если OSIV включен. Что я неправильно понимаю по поводу OSIV и @Transactional?

Ответы [ 2 ]

1 голос
/ 19 апреля 2019

Открыть сеанс в представлении (OSIV) оставляет сеанс открытым, чтобы иметь возможность лениво загружать ассоциации при рендеринге представления. Но это не оставляет транзакцию открытой.

Изменения уже зафиксированы, и более поздние изменения не будут сохраняться, поскольку более поздние изменения никогда не сбрасываются и не фиксируются (и поскольку изменения не должны происходить в первую очередь)

OSIV в любом случае является грязным хаком, поскольку данные, загруженные после совершения транзакции, возможно, несовместимы с данными, загруженными внутри транзакции. Я бы избежал этого. См. https://vladmihalcea.com/the-open-session-in-view-anti-pattern для более подробной информации.

0 голосов
/ 19 апреля 2019

carRepo. Сохранить или сохранить? если вы используете слияние, получите результат слияния!

"Persist берет экземпляр объекта, добавляет его в контекст и управляет этим экземпляром (т. Е. Будут отслеживаться будущие обновления объекта).

Слияние создает новый экземпляр вашей сущности, копирует состояние из предоставленной сущности и управляет новой копией. Экземпляр, который вы передаете, не будет управляемым (любые внесенные вами изменения не будут частью транзакции - если вы снова не вызовете merge). " как описано в этот ответ

...