簡體   English   中英

Hibernate 持久化實體而不獲取關聯對象。 僅憑身份證

[英]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 中的相同操作

獲取一個(用戶 ID)

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM