[英]JPA/Hibernate OneToOne association, persist call inserts entity with null Id
[英]Hibernate persist entity without fetching association object. just by id
我在 2 個實體之間有一個簡單的關聯:
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;
...
}
然后我從客戶端獲取一些用戶 ID。 例如,userId == 5;
要與用戶一起保存汽車,我需要執行以下操作:
User user = ... .findOne(userId);
Car car = new Car();
car.setUser(user);
... .save(car);
我的問題是:
我可以在不獲取用戶的情況下保留汽車記錄嗎?
與我使用本機 SQL 查詢所做的類似:只需在 Car 表中插入像 string(long) 這樣的 userId。
使用 2nd lvl 緩存會更快,但我認為我不需要做額外的動作。
我不想使用原生 Query 的主要原因是我的項目中有更困難的關聯,我需要多次 .save(car) 。 另外我不想手動控制查詢執行的順序。
如果我使用 session.createSQLQuery("insert into .....values()") 休眠的批量插入工作正常嗎?
如果我錯了糾正我。
提前致謝!
更新:
實際上映射類似於:
User 和 Car 之間存在 @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'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);
“我可以在不獲取用戶的情況下保留汽車記錄嗎?”
是的,這是 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 的批量插入工作正常嗎?
不,不會。 查詢會立即執行。
如果有人正在使用 spring JPA,則可以使用該方法完成 Spring JPA 中的相同操作
Hibernate 用戶可以實現這個方法:
public <T extends Object> T getReferenceObject(Class<T> clazz, Serializable id) {
return getCurrentSession().get(clazz, id);
}
並像這樣調用:
MyEntity myEntity = getRefererenceObject(MyEntity.class, 1);
您可以根據您的實體模型將 id 類型更改為 Integer 或 Long。 或者,如果所有實體都有一個基類,則 T 可以從您的 BaseEntity 繼承。
以下方法對我有用:
User user = new User();
user.setId(userId);
car.setUser(user);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.