Сохранение сущностей, извлеченных из запроса в спящем режиме - PullRequest
2 голосов
/ 22 февраля 2012

У меня есть базовый вопрос Hibernate / JPA. Я хочу найти лучшее решение решение для сохранения сущностей. У меня есть список сущностей, и многие из них могут быть изменены, поэтому я хочу сохранить их все сразу.

Я считаю, что все в значительной степени стандартно. (Просто пример кода для удобства чтения)

Сущность: Автомобиль

@Entity
public class Car implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    private id;

    private String model;

    // .... Setter

    // .... Getter

}

Класс обслуживания: Автосервис

@Named
@Transactional
public class CarServiceImpl implements CarService {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<Car> findAll() {
        TypedQuery<Car> q = entityManager.createQuery(
                "FROM Car", Car.class);
        return q.getResultList();
    }

    @Override
    public void saveEntity (Car car) {
        /* What exactly am I doing here? */
    }
}

Контроллер: CarEditController

@Named
public class CarEditController implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private CarService carService;

    private List<Car> cars;

    public List<Car> getCars () {
        return carService.findAll();
    }

    public void setCars (List<Car> cars) {
        this.cars = cars;
    }

    public void btn_newClick() {
        Car newCar = new Car();
        car setModel("BMW");

        cars.add(newCar);
    }

    public void btn_saveClick() {
        for (Car car : cars) {
            carService.saveEntity(car);
        }
    }
}

Я нашел немало способов спасти сущность. Очевидными являются entityManager.merge (car) для существующих объектов и entityManager.persist (car) для новых. Теоретически это легко, но как узнать, какая сущность нова?

Документация предлагает entityManager.flush () , которая теоретически обновляет все существующие и вставляет все новые сущности. Это работает, но только если я получаю объект с помощью find () .

Вопрос:

Я хочу получить все объекты за один шаг, добавить новые и затем сохранить их все в одном методе (btn_saveClick ()). Как лучше всего выполнить эту задачу?

Ответы [ 3 ]

2 голосов
/ 22 февраля 2012

Я не знаком с JPA, но в спящем режиме есть session.saveOrUpdate()

for(Car car : existingAndNewCars)
{
    session.saveOrUpdate(car);
}

Обновление:

Как я понимаю JPA, его merge похоже на session.merge, что совершенно отличается, поскольку он не отслеживает изменения в объекте, предоставленном ему, в то время как persist / save / update / saveOrUpdate будет отслеживать последующие изменения в автомобиле, что приводит к незначительным различиям

Обновление:

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

@Override
public void saveEntity (Car car) {
    if (car.getId() == null) {
        entityManager.persist(car);
}

без тонкой разницы в постоянстве и слиянии

2 голосов
/ 22 февраля 2012

Просто проверьте, установлен ли @Id.

@Override
public void saveEntity (Car car) {
    if (car.getId() == null) {
        entityManager.persist(car);
    } else {
        entityManager.merge(car);
    }
}

Однако более распространенным подходом является предоставление отдельных create() и update() методов обслуживания.

1 голос
/ 22 февраля 2012

Операция очистки будет работать со всеми объектами в текущем сеансе Hibernate - новые объекты вставляются, а существующие объекты обновляются, если они изменились.

Вам необходимо убедиться, что все сущности присоединены к сеансу. Вы делаете это с помощью слияния, как вы правильно сказали. После того, как вы загрузили все объекты, сеанс закрывается, когда транзакция заканчивается. Тогда ваши объекты находятся в отдельном состоянии, то есть были сохранены, но больше не привязаны к сеансу.

Я бы изменил вашу логику, чтобы ваш carService # save занял список. Затем он может вызывать слияние для каждого (прикрепляя их к сеансу). Затем, когда ваша транзакция завершится, Hibernate сразу сбросит все изменения в базу данных.

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