java Hibernate 持久化实体而不获取关联对象。仅凭身份证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31929447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate persist entity without fetching association object. just by id
提问by InsFi
I have an simple association between 2 entities:
我在 2 个实体之间有一个简单的关联:
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:
然后我从客户端获取一些用户 ID。例如,userId == 5;
要与用户一起保存汽车,我需要执行以下操作:
User user = ... .findOne(userId);
Car car = new Car();
car.setUser(user);
... .save(car);
My question is:
Can I persist car record without fetching user?
我的问题是:
我可以在不获取用户的情况下保留汽车记录吗?
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?
与我使用本机 SQL 查询所做的类似:只需在 Car 表中插入像 string(long) 这样的 userId。
使用 2nd lvl 缓存会更快,但我认为我不需要做额外的动作。
我不想使用原生 Query 的主要原因是我的项目中有更困难的关联,我需要多次 .save(car) 。另外我不想手动控制查询执行的顺序。
如果我使用 session.createSQLQuery("insert into .....values()") 休眠的批量插入工作正常吗?
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:
User 和 Car 之间存在@ManyToMany 关联。但交叉表也是一个命名实体,例如,Passanger。所以映射是下一个:
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);
采纳答案by Dragan Bozanovic
"Can I persist car record without fetching user?"
“我可以在不获取用户的情况下保留汽车记录吗?”
Yes, that's one of the good sides of Hibernate proxies:
是的,这是 Hibernate 代理的优点之一:
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:
这里的关键点是使用EntityManager.getReference:
Get an instance, whose state may be lazily fetched.
获取一个实例,其状态可能会被延迟获取。
Hibernate will just create the proxy based on the provided id, without fetching the entity from the database.
Hibernate 只会根据提供的 id 创建代理,而不会从数据库中获取实体。
"If I use session.createSQLQuery("insert into .....values()") will the Hibernate's batch insert work fine?"
“如果我使用 session.createSQLQuery("insert into .....values()") Hibernate 的批量插入工作正常吗?
No, it will not. Queries are executed immediately.
不,不会。查询会立即执行。
回答by ?smail Yavuz
Hibernate users can implement this method:
Hibernate 用户可以实现这个方法:
public <T extends Object> T getReferenceObject(Class<T> clazz, Serializable id) {
return getCurrentSession().get(clazz, id);
}
And call like:
并像这样调用:
MyEntity myEntity = getRefererenceObject(MyEntity.class, 1);
You can change id type to Integer or Long as per your entity model. Or T can be inherited from your BaseEntity if you have one base class for all entities.
您可以根据您的实体模型将 id 类型更改为 Integer 或 Long。或者,如果所有实体都有一个基类,则 T 可以从您的 BaseEntity 继承。