Hibernate сохраняет объект без объекта ассоциации. просто по id
У меня есть простая связь между двумя объектами:
public class Car {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
...
}
а также
public class User {
@Id
@GeneratedValue
@Column(name = "user_id")
private long userId;
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Set<Car> cars;
...
}
Затем я получаю идентификатор пользователя от клиента. Например, userId == 5;
Чтобы сохранить автомобиль с пользователем, мне нужно сделать следующее:
User user = ... .findOne(userId);
Car car = new Car();
car.setUser(user);
... .save(car);
Мой вопрос:
Могу ли я сохранить запись автомобиля без запроса пользователя?
Точно так же, как я бы сделал, используя собственный SQL-запрос: просто вставьте userId, как string (long) в Car car.
Со вторым кэшем lvl он будет быстрее, но, на мой взгляд, мне не нужно делать дополнительные движения.
Основная причина, по которой я не хочу использовать собственный запрос, заключается в том, что у меня есть гораздо более сложные ассоциации в моем проекте, и мне нужно много.save(car). Также я не хочу вручную контролировать порядок выполнения запросов.
Если я использую session.createSQLQuery("insert into..... values ()"), то вставка в Hibernate работает нормально?
Поправьте меня если я ошибаюсь.
Заранее спасибо!
ОБНОВИТЬ:
На самом деле отображение аналогично:
Существует ассоциация @ManyToMany между пользователем и автомобилем. Но перекрестная таблица также является сущностью, которая называется, например, Passanger. Итак, следующее следующее:
public class User{
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", targetEntity = Passenger.class)
private Set<Passenger> passengers;
}
Перекрестное предприятие
@IdClass(value = PassengerPK.class)
public class Passenger {
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "car_id")
private Car car;
... other fields ...
}
Автомобиль:
public class Car {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "car", targetEntity = Passenger.class, cascade = CascadeType.ALL)
private Set<Passenger> passengers;
}
И код:
List<User> users = ... .findInUserIds(userIds); // find user records where userId is IN userIds - collection with user Ids
Car car = new Car(); //initialization of car fields is omitted
if (users != null) {
car.setPassengers(new HashSet<>(users.size()));
users.forEach((user) -> car.getPassengers().add(new Passenger(user, car)));
}
... .save(car);
Ответы
Ответ 1
"Могу ли я сохранить запись автомобиля, не выбирая пользователя?"
Да, это одна из хороших сторон прокси-серверов Hibernate:
User user = entityManager.getReference(User.class, userId); // session.load() for native Session API
Car car = new Car();
car.setUser(user);
Ключевым моментом здесь является использование EntityManager.getReference:
Получите экземпляр, чье состояние может быть лениво взято.
Hibernate просто создаст прокси-сервер, основанный на предоставленном id, не получая объект из базы данных.
"Если я использую session.createSQLQuery(" insert into..... values () "), то будет ли работать пакетная вставка Hibernate?"
Нет, не будет. Запросы выполняются немедленно.