休眠保存实体
Posted
技术标签:
【中文标题】休眠保存实体【英文标题】:Hibernate Save Entity 【发布时间】:2012-09-09 01:58:39 【问题描述】:我有 2 个实体,车辆和司机。车辆有司机。在 Hibernate 生成的 Vehicle 类中,这种表示法由...表示。
public class Vehicle
private Driver driver;
...
...
...
在 DB 中以下是场景...
table vehicle
id INT
name VARCHAR(20)
driverId INT
table driver
id INT
name VARCHAR(45)
我正在创建一个载具并想分配一个现有的驱动程序。使用 Hibernate,当我创建一个 Vehicle 对象并保存它时,我必须执行以下操作...
// Load Driver
Driver driver = (Driver) session.load(Driver.class, Integer.parseInt(iKnowTheDriverId));
// Create Vehicle
Vehicle v = new Vehicle();
v.setDriver(driver);
我是否需要每次都加载相应的驱动程序实体,还是只设置驱动程序 ID?
提前谢谢...
SG
【问题讨论】:
【参考方案1】:在保存新的Vehicle
时,您需要获得对相应Driver
的引用。
// Load Driver
Driver driver = (Driver) session.load(Driver.class, driverId);
// Create Vehicle
Vehicle v = new Vehicle();
v.setDriver(driver);
v.setName("someName");
session.save(vehicle);
但是使用session.load()
得到对应的Driver
是避免SQL SELECT
到数据库的好选择。 driver
对象在您读取其属性之前不会完全初始化。然后才发出SQL SELECT
。
【讨论】:
这也可能导致EntityNotFound?但这正是我想要避免的。在 SQL 中,我只需更新表列中的驱动程序 ID。我想要一个类似的方式在这里...... "这也可能导致EntityNotFound?"不。如果您知道驱动程序的 id,hibernate 将始终返回引用。我假设驱动程序已经保存在数据库中。【参考方案2】:你可以这样做:
Driver temp = new Driver();
temp.setId(iKnowTheDriverId);
v.setDriver(temp);
session.merge(v);
保存方法之间可能存在一些差异,但如果您使用 Session#merge() 它应该可以工作。然后它将通过检查它们的 id 将分离的驱动程序与现有的驱动程序合并,并且分离对象中的空值不会覆盖持久状态中的非空值。只需确保在从 Vehicle 到 Driver 的引用中具有 CascadeType.MERGE/ALL 即可。
【讨论】:
在什么情况下不起作用?从 Vehicle 到 Driver 的关联是否有 CascadeType.MERGE?【参考方案3】:try
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(userDetails);
Long userId = userDetails.getId();
session.getTransaction().commit();
session.close();
logger.info("Successfully added the user");
return userId;
catch (Exception e)
logger.error("error in saving the user in user table", e);
【讨论】:
以上是关于休眠保存实体的主要内容,如果未能解决你的问题,请参考以下文章