Подтвердить что ты не робот

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);
4b9b3361

Ответ 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?"

Нет, не будет. Запросы выполняются немедленно.