我有两个实体之间的简单关联:
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)
| 归档时间: |
|
| 查看次数: |
12870 次 |
| 最近记录: |