本文介绍了Hibernate持久化实体而不需要获取关联对象。只是由id的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =user_id)
私人用户用户;

...

}

  public class User {

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

...

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

...

}

然后我从客户端获得一些用户ID。例如,userId == 5;

为了节省汽车用户,我需要做下一步:

  User user = ... .findOne(userId); 
汽车车=新车();
car.setUser(user);
... .save(car);



类似于使用本地SQL查询所做的操作:只需在Car表中插入userId,如string(long)。 >

第二个lvl缓存会更快,但在我看来,我不需要做额外的移动。

我不想使用本机查询的主要原因是因为我的项目中有更多困难的关联,我需要多次存储(汽车)。我也不想手动控制查询执行的顺序。


如果我使用session.createSQLQuery(insert into ..... values()),Hibernate的批量插入工作正常?






如果我错了,请纠正我。


提前致谢!



更新:


实际上,映射类似于:



用户和汽车之间存在@ManyToMany关联。但是交叉表也是一个被命名为例如Passanger的实体。所以映射是下一步:


$ p $ public class User {
@OneToMany(fetch = FetchType.LAZY, mappedBy =user,targetEntity = Passenger.class)
private Set< Passenger>乘客;

交叉实体

 @IdClass(value = PassengerPK.class)
public class Passenger {

@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =user_id)
私人用户用户;

@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =car_id)
私家车;

...其他栏位...

}

Car实体:

  public class Car {
@OneToMany(fetch = FetchType.LAZY,mappedBy = car,targetEntity = Passenger.class,cascade = CascadeType.ALL)
private Set< Passenger>乘客;
}

和代码:

 列表<用户> users = ... .findInUserIds(userIds); //找到userId所在的用户记录userIds  - 包含用户ID的集合
Car car = new Car();如果(用户!= null){
car.setPassengers(new HashSet<>(users.size())),则省略汽车字段的初始化
; ((用户) - > car.getPassengers()。add(新Passenger(用户,汽车)));
users.forEach
}
... .save(car);


解决方案

用户?



是的,这是Hibernate代理的优点之一:

  User user = entityManager.getReference(User.class,userId); // session.load()用于本地Session API 
Car car = new Car();
car.setUser(user);

关键在于使用:

Hibernate将创建如果我使用session.createSQLQuery(insert into ..... values),那么可以使用session.createSQLQuery(insert into ..... values ())Hibernate的批插入工作正常吗?



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


I have an simple association between 2 entities:

public class Car {

    ...

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

    ...

}

and

public class User {

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

    ...

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

    ...

}

Then I get some user id from client. For example, userId == 5;
To save car with user I need to do next:

User user = ... .findOne(userId);
Car car = new Car();
car.setUser(user);
... .save(car);

Similarly like I would do by using native SQL query: just insert userId like string(long) in Car table.

With 2nd lvl cache it will be faster but in my opinion I don't need to do extra movements.

The main reason that I don't want to use native Query is because I have much more difficult associations in my project and I need to .save(car) multiple times. Also i don't want to manually control order of query executions.

If I use session.createSQLQuery("insert into .....values()") will the Hibernate's batch insert work fine?



Correct me if I'm wrong.

Thanks in advance!

UPDATE:

Actually the mapping is similar to:

There is @ManyToMany association between User and Car. But cross table is also an entity which is named, for example, Passanger. So the mapping is next:

public class User{
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", targetEntity = Passenger.class)
    private Set<Passenger> passengers;
}

Cross entity

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

}

Car entity:

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

And the code:

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);
解决方案

"Can I persist car record without fetching user?"

Yes, that's one of the good sides of Hibernate proxies:

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

The key point here is to use EntityManager.getReference:

Hibernate will just create the proxy based on the provided id, without fetching the entity from the database.

"If I use session.createSQLQuery("insert into .....values()") will the Hibernate's batch insert work fine?"

No, it will not. Queries are executed immediately.

这篇关于Hibernate持久化实体而不需要获取关联对象。只是由id的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 08:44
查看更多