Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java实现OneToMany的最佳实践_Java_Sql_Hibernate_Design Patterns_Jpa - Fatal编程技术网

使用Java实现OneToMany的最佳实践

使用Java实现OneToMany的最佳实践,java,sql,hibernate,design-patterns,jpa,Java,Sql,Hibernate,Design Patterns,Jpa,简短版本: 假设我在父母和孩子之间有一对多的关系。现在在Java代码中,最好的做法是读取父对象,从数据库中获取它,并在其中应用一些称为addChild的方法,还是直接创建一个子对象并将其持久化而不读取父对象 长版本 让我们假设这个父母和孩子来自 现在考虑我有一个网页,员工可以在这里添加电话号码。因此,我已经拥有父员工的id,但没有完整的员工对象 1-当然,我通过JPA映射从数据库中获取整个Employee对象。然后我应用employee.addphone之类的方法。这导致了两个问题 2-我创建了

简短版本:

假设我在父母和孩子之间有一对多的关系。现在在Java代码中,最好的做法是读取父对象,从数据库中获取它,并在其中应用一些称为addChild的方法,还是直接创建一个子对象并将其持久化而不读取父对象

长版本

让我们假设这个父母和孩子来自

现在考虑我有一个网页,员工可以在这里添加电话号码。因此,我已经拥有父员工的id,但没有完整的员工对象

1-当然,我通过JPA映射从数据库中获取整个Employee对象。然后我应用employee.addphone之类的方法。这导致了两个问题

2-我创建了电话对象,但是一个错误的employee对象只包含员工的id,我是否坚持


这方面的最佳实践是什么?

最佳实践是维护协会的双方。这样可以确保您不会使用不一致的对象图。但是,它可能会降低服务的性能,特别是如果它所做的只是创建一个与员工链接的新电话。事实上,它将加载员工及其所有现有手机的状态

请注意,JPA只关心关联的所有者方:设置新手机的雇员就足以在数据库中创建关联

如果您选择使用第二种解决方案,则不应创建假Employee对象。您应该从EntityManager获取员工参考:

Employee e = em.getReference(Employee.class, employeeId);
Phone phone = new Phone();
phone.setEmployee(e);
em.persist(phone);

getReference不生成任何SQL查询。它返回一个未初始化的代理,这就是您所需要的。优点是,如果该方法最终变得更复杂,并调用员工的任何方法,则将加载员工的实际状态。

最佳做法是维护关联的双方。这样可以确保您不会使用不一致的对象图。但是,它可能会降低服务的性能,特别是如果它所做的只是创建一个与员工链接的新电话。事实上,它将加载员工及其所有现有手机的状态

请注意,JPA只关心关联的所有者方:设置新手机的雇员就足以在数据库中创建关联

如果您选择使用第二种解决方案,则不应创建假Employee对象。您应该从EntityManager获取员工参考:

Employee e = em.getReference(Employee.class, employeeId);
Phone phone = new Phone();
phone.setEmployee(e);
em.persist(phone);

getReference不生成任何SQL查询。它返回一个未初始化的代理,这就是您所需要的。优点是,如果该方法最终变得更复杂,并调用雇员的任何方法,则将加载雇员的实际状态。

谢谢,但是如果getReference返回的雇员未初始化,则可能根本不存在,对吗?我的意思是,实体经理可以返回一个不存在的员工?是的,由于违反了外键约束,您在保存电话时会出现异常。使用get也没什么不同:em只会在employee存在时返回它,但是另一个事务很可能会在employee从数据库加载之后删除它。外键约束是保证连贯性的因素。谢谢,现在已经清楚了。看来getReference可以像find一样出色地完成这项工作,并且具有更好的性能。然而,在你的回答中,我明白发现是更好的做法。正确吗?不。如果您只需要一个引用,那么getReference就可以完成这项工作。谢谢,但是如果getReference返回的员工未初始化,那么它可能根本不存在?我的意思是,实体经理可以返回一个不存在的员工?是的,由于违反了外键约束,您在保存电话时会出现异常。使用get也没什么不同:em只会在employee存在时返回它,但是另一个事务很可能会在employee从数据库加载之后删除它。外键约束是保证连贯性的因素。谢谢,现在已经清楚了。看来getReference可以像find一样出色地完成这项工作,并且具有更好的性能。然而,在你的回答中,我明白发现是更好的做法。是这样吗?不是。如果你只需要一个参考,那么getReference就可以完成这项工作。