使用hibernate保存从查询中获取的实体

时间:2012-02-22 10:37:29

标签: java hibernate jpa

我有一个基本的Hibernate / JPA问题。我想为保存实体找到最佳实践解决方案。我有一个实体列表,其中许多可能会被修改,所以我想立即保存它们。

我相信一切都非常标准。 (仅出于可读性原因的示例代码)

实体:汽车

@Entity
public class Car implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    private id;

    private String model;

    // .... Setter

    // .... Getter

}

服务类:CarService

@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)。理论上这很容易,但我怎么知道哪个实体是新的?

documentation建议 entityManager.flush(),理论上更新所有现有实体并插入所有新实体。只有当我使用 find()获取实体时,它才有效。

问题:

我想一步获取所有实体,添加新实体,然后将它们全部保存在一个方法中(btn_saveClick())。如何最好地完成这项任务?

3 个答案:

答案 0 :(得分:2)

我不熟悉JPA,但在休眠状态下有session.saveOrUpdate()

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

更新

据我了解JPA,其mergesession.merge类似,完全不同,因为在persist / save / update / saveOrUpdate /时,它不会跟踪对其提供的对象的更改@Override public void saveEntity (Car car) { if (car.getId() == null) { entityManager.persist(car); } / {{1}}会跟踪对汽车的后续更改,从而导致细微的差异

更新

因为您使用相同的实体管理器,所以

就足够了
{{1}}

没有持久和合并的细微差别

答案 1 :(得分:2)

只需检查是否已设置@Id

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

然而,更常见的方法是提供单独的create()update()服务方法。

答案 2 :(得分:1)

刷新操作将对当前Hibernate会话中的所有实体进行操作 - 插入新实体并更新现有实体。

您需要确保所有实体都附加到会话。您正确地说,使用合并执行此操作。加载所有实体后,会话在事务结束时关闭。然后,您的对象处于分离状态,即已保留但不再连接到会话。

我会修改你的逻辑,以便你的carService#save获取一个List。然后它可以在每个上调用merge(将它们附加到会话)。然后,当您的事务结束时,Hibernate将立即刷新对数据库的所有更改。