Hibernate持久化实体而不提取关联对象.只是通过id

Ins*_*sFi 26 java hibernate

我有两个实体之间的简单关联:

public class Car {

    ...

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    ...

}
Run Code Online (Sandbox Code Playgroud)

public class User {

    @Id
    @GeneratedValue
    @Column(name = "user_id")
    private long userId;

    ...

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    private Set<Car> cars;

    ...

}
Run Code Online (Sandbox Code Playgroud)

然后我从客户端获得一些用户ID.例如,userId == 5;
为了节省汽车用户,我需要做下一步:

User user = ... .findOne(userId);  
Car car = new Car();
car.setUser(user);
... .save(car);
Run Code Online (Sandbox Code Playgroud)

我的问题是:
我可以在没有取用用户的情况下坚持记录汽车记录吗?

与我使用本机SQL查询一样:只需在Car表中插入userId,如string(long).

使用第二个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;
}
Run Code Online (Sandbox Code Playgroud)

跨实体

@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 ...

}
Run Code Online (Sandbox Code Playgroud)

汽车实体:

public class Car {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "car", targetEntity = Passenger.class, cascade = CascadeType.ALL)
    private Set<Passenger> passengers;
}
Run Code Online (Sandbox Code Playgroud)

和代码:

List<User> users = ... .findInUserIds(userIds); // find user records where userId is IN userIds - collection with user Ids
Car car = new Car();       //initialization of car's fields is omitted
if (users != null) {
    car.setPassengers(new HashSet<>(users.size()));
    users.forEach((user) -> car.getPassengers().add(new Passenger(user, car)));
}
... .save(car);
Run Code Online (Sandbox Code Playgroud)

Dra*_*vic 21

"我可以在没有取用用户的情况下保留汽车记录吗?"

是的,这是Hibernate代理的好处之一:

User user = entityManager.getReference(User.class, userId); // session.load() for native Session API  
Car car = new Car();
car.setUser(user);
Run Code Online (Sandbox Code Playgroud)

这里的关键是使用EntityManager.getReference:

获取一个实例,其状态可能会被懒惰地取出.

Hibernate将根据提供的id创建代理,而无需从数据库中获取实体.

"如果我使用session.createSQLQuery("insert into ..... values()"),Hibernate的批量插入工作会不会很好?"

不,它不会.查询立即执行.


小智 5

如果有人使用 Spring Data JPA:同样可以在 Spring Data JPA 中使用以下方法来实现

JpaRepository.getReferenceById(ID id)

这取代了前者 getOne(ID)