2017-06-03 79 views
2

我有一个关于与thymeleaf和关系管理使用springboot的问题。Springboot关系管理

我有一个需要充分的双向三个对象:

OBJ1(多) - TO - (一)OBJ2(一) - TO - (多)OBJ 3

他们设置为:

public class Obj1 { 
@Id 
private long id; 
@ManyToOne(cascade=CascadeType.ALL) 
private Obj2 obj2; 

public class Obj2 { 
@Id 
private long id; 
@OneToOne 
private User planUser 
// Other fields 
@OneToMany(mappedby = obj2) 
private List<Obj1> obj1; 
@OneToMany(mappedby obj2) 
private List<Obj3> obj3; 

public class Obj3 { 
@Id 
private Long id; 
@ManyToOne 
private Obj2 obj2; 

在视图方面,有一个名为view1的页面,用于填充Obj1。这工作。

有一个名为view2的另一个页面: 1. OBJ1显示一些基本的细节 2.填充/更新OBJ 2和OBJ 3

的问题是如何提交视图2更新/创建OBJ 2和OBJ 3。

我试图让控制器去呼吁OBJ1服务方法:

@Override 
@Transactional 
public Obj1 associateObj1ToObj2(Long Obj2Id, Obj1 newObj1) { 
    final Obj2 obj2 = ojbj2Repository.findOne(obj2Id); 
    obj2.getObj1().add(newObj1); 
    newObj1.setObj2(obj2); 
    return obj1Repository.save(newObj1); 
} 

问题:

  1. 即使我有@Post形式控制器obj2Repo.save (obj2)当我尝试在associateObj1ToObj2中调用它时 - 应该保存的值(如userPlan)不是。为什么?
  2. 在上述情况下,单个根对象是否可以并且应该为多个页面提供服务? (建议的替代方案显然是创建一个混合类用于支持页面view2 - 链接到git示例是伟大的(这就是所谓的DTO))。
  3. 是否纠正springboot不会处理关系设置,至少在一个孩子的孩子需要被更新的情况下)
  4. 什么是Hibernate的Session的生活吗?

注意:许多关系真的应该叫几个 - 对关系的藏品几乎总是人数少于10

这个答案似乎是有一定的关系:Could not initialize proxy - no Session

+0

IMO,你最好一次问一个问题。如果你花时间提供一个[最小,完整,可验证的例子](/ help/mcve) –

+0

这将是非常棘手的,因为我会很难看到你在做什么,将需要重复项目,然后重构和混淆。 –

+0

@AndyWilkinson做这个帮助:https://github.com/bigalnz/mvce/tree/master –

回答

3

我正想在这里讨论使用对话的基于支持框架的双方,但是,我认为这在事后看来是无关紧要的。虽然这些框架可以帮助处理视图/控制器/域对象一致性所需的样板文件,但我不认为应该如何设计控制器和视图来与用户交互。

我会说大多数开发人员经常采取发送他们的实体bean到视图的立场作为支持bean表示。对于小型非复杂的imo游戏项目来说,这些项目就足够了,但通常这种方法在实体关系或UI布局变得复杂时开始崩溃。

通过使用非实体作为您的视图的后备bean,您可以让您的UI和视图有机地增长,而不受制定数据库表和持久性关系的决策和选择的约束。这也意味着您可以利用数据库模式设计选择,而不会影响您在UI中如何布局和与用户交互。在重构代码或通过UI更改改善用户体验期间,这变得非常有用。

即使我有@Post形式控制器obj2Repo.save(OBJ 2)当我试图回忆起来associateObj1ToObj2-应该已经保存(如userPlan)的值都没有。为什么?

难道形式实际上该信息发送回在后?

让我们假设我们有一个非常简单的对象:

class SomeEntity { 
    private Integer id; 
    private String name; 
    private String address; 
    private List<String> nicknames; 
} 

如果所有的形式允许为用户更改其地址,但形式实际上并没有给我们回值name,它会当我们检查控制器中的SomeEntity实例时,请将其设为空。那真的是我们想要的吗?如果你有关系,也会发生同样的情况。如果表单实际上没有将我们的昵称列表发回给我们,那么这种关系也将是空白的。

对我来说,这凸显为什么支持豆意见最终应代表视图的使用情况,并不仅如此。我们确切地知道视图需要和返回哪些字段,并且我们管理数据的生命周期,而不依赖于我们的实体模型在我们的应用程序和持久性提供者的角度上被认为是有效的数据。

在上述情况下,单个根对象是否可以并且应该有多个页面? (建议的替代方案显然是创建一个混合类用于支持页面view2 - 链接到git示例是伟大的(这就是所谓的DTO))。

这是一个简单的喜好设计选择。一个视图的单个后台bean非常好。我们有理由认为,虽然多个后备豆:

  1. 对待你的观点为更小的块组成。
    这允许代码在其他UI布局中重用这些组件。
  2. 隔离可变VS不变的表单属性。

通常我更喜欢(1)作为默认选择。我主张使用(2)的唯一情况是视图具有相当数量的只读字段给用户上下文信息,并且它们只能改变总体属性数量的一小部分。

是否纠正springboot不会处理关系设置,至少在一个孩子的孩子需要被更新的情况下)

这不是一个springboot关注。正如我之前提到的,这种情况发生的很多原因取决于其他因素。

  1. 什么数据在窗体中被序列化并反过来被发送回控制器。
  2. 表格是如何组织的,它是否被正确地序列化。
  3. 您是否在使用对话框架/配置。

什么是Hibernate会话的生命?

这取决于您的配置设置。

春天开机后允许使用的OpenSessionInViewOpenEntityManagerInView过滤器Hibernate会话的生命周期延伸到web请求已经结束点。在我看来,除了简单的原型外,你不应该使用这个,因为它带有它自己的问题,包括性能和意外的插入,更新和基于糟糕的假设或代码的删除。

+0

非常有帮助 - 我对冬眠魔法的细节感到困惑 –