如何实现修改"JPA entitiy-object structure"的参数变化?
How to implement a parameter variation that modifies a "JPA entitiy-object structure"?
短版:
我想从数据库加载对象树,然后在内存中修改它(通过应用设置文件)以便能够执行参数变化。是否有这样做的最佳实践? JPA 是否为此提供了一些支持,例如从额外的 "diff-database" 更新持久性上下文?是否有支持 JPA 持久性的参数 variation/sweep/batch 框架?
长版:
我有一个模拟程序 'Simulator',它使用 JPA (Hibernate) 从 MySQL 数据库加载其业务对象:您可以想象从数据库加载的对象的树结构。业务对象的类对应数据库中的tables(foo,bar,qux)。
对象树:
foo_root (id =1)
+ bar_first (id =1)
++ qux_large (id = 1)
+ bar_second (id = 2)
++ qux_small (id = 2)
++ qux_medium (id = 3)
++ qux_huge (id = 4)
树中的一个对象(例如 'bar_first' )对应于数据库中的一行 table 并且在 table 中有一个唯一的 ID。对象的属性值对应于 table 的列中的条目。例如 table 'qux' 包含一个列 'color' 并且对象 'qux_large' (table qux 中的 id 1)具有属性 color = green.
模拟程序适用于单次模拟。现在我想实现第二个程序 'SweepMaster',它能够执行参数变化/扫描/批处理:
- 用户指定了一些要修改的参数以及这些参数的取值范围。参数可能对应于完整的对象 (-id) 或对象树中对象的属性。
- SweepMaster 创建一组输入文件并为每个单独的输入文件调用模拟器。
- 模拟器使用 JPA 加载对象树并通过应用来自单个输入文件的数据修改树(某些 objects/attributes)。然后它执行模拟。
- 模拟器完成后,SweepMaster 将使用下一个输入文件开始下一个模拟。
一个单独的输入文件指定例如
- 加载'foo_root'开头的对象树(id=1)
- 使用 color=yellow 作为 'qux_large'
- 用对象 'bar_third' (id = 3) 替换完整的对象 'bar_second'
另一个输入文件可能指定为
- 使用另一个对象树,从 'foo_alternative_root' (id = 2)
开始
- 对 'foo_alternative_root' 使用 memory_size=500
我应该如何实现对对象树的修改?
选项:
我想到了以下选项:
I. 模拟器从数据库加载一个对象树然后修改内存中的对象树.
a) 输入文件通过对象树传递,树中的每个对象检查是否应该修改,如果是,则更改其属性或交换一些子对象.为了能够交换子对象,它必须能够从数据库中加载新的子对象。 (或者这样的新子对象必须在开始时确定并与输入文件一起通过树。)
b) 设置控制器更改整棵树的属性,例如通过反思。它不需要遍历整棵树。它只处理输入文件中给出的一些特定树位置。
II. 模拟器加载完整的数据库并将其复制到内存数据库。它通过使用 SQL 查询调整内存数据库来应用输入文件。在第三步中,它使用 JPA 从修改后的内存数据库中加载对象树。
III. SweepMaster 在原始数据库中创建对象树的许多临时副本 ] 并根据用户输入修改它们。然后它指示模拟器使用那些改编的副本。参数变化完成后,SweepMaster 删除临时文件。
是否有进一步的解决方案?您在执行类似任务时有何经验?
我决定选择选项 I b),我将为可在参数变化中使用的字段引入一些自定义注释,例如
@ParameterPath("foo_root")
@参数("qux_huge")
foo.baa = 5
这将使我可以选择进行内部重构(例如更改字段的名称),而无需直接更改参数变化的输入文件。
设置控制器将遍历输入文件并通过反射搜索相应的注释字段。它还会要求工厂创建应该用作该字段值的对象。最后设置控制器将通过反射设置字段的值。
如果我想为我的参数变体使用具有新类型的附加字段,我将必须注释该字段并为新类型扩展工厂。
短版:
我想从数据库加载对象树,然后在内存中修改它(通过应用设置文件)以便能够执行参数变化。是否有这样做的最佳实践? JPA 是否为此提供了一些支持,例如从额外的 "diff-database" 更新持久性上下文?是否有支持 JPA 持久性的参数 variation/sweep/batch 框架?
长版:
我有一个模拟程序 'Simulator',它使用 JPA (Hibernate) 从 MySQL 数据库加载其业务对象:您可以想象从数据库加载的对象的树结构。业务对象的类对应数据库中的tables(foo,bar,qux)。
对象树:
foo_root (id =1)
+ bar_first (id =1)
++ qux_large (id = 1)
+ bar_second (id = 2)
++ qux_small (id = 2)
++ qux_medium (id = 3)
++ qux_huge (id = 4)
树中的一个对象(例如 'bar_first' )对应于数据库中的一行 table 并且在 table 中有一个唯一的 ID。对象的属性值对应于 table 的列中的条目。例如 table 'qux' 包含一个列 'color' 并且对象 'qux_large' (table qux 中的 id 1)具有属性 color = green.
模拟程序适用于单次模拟。现在我想实现第二个程序 'SweepMaster',它能够执行参数变化/扫描/批处理:
- 用户指定了一些要修改的参数以及这些参数的取值范围。参数可能对应于完整的对象 (-id) 或对象树中对象的属性。
- SweepMaster 创建一组输入文件并为每个单独的输入文件调用模拟器。
- 模拟器使用 JPA 加载对象树并通过应用来自单个输入文件的数据修改树(某些 objects/attributes)。然后它执行模拟。
- 模拟器完成后,SweepMaster 将使用下一个输入文件开始下一个模拟。
一个单独的输入文件指定例如
- 加载'foo_root'开头的对象树(id=1)
- 使用 color=yellow 作为 'qux_large'
- 用对象 'bar_third' (id = 3) 替换完整的对象 'bar_second'
另一个输入文件可能指定为
- 使用另一个对象树,从 'foo_alternative_root' (id = 2) 开始
- 对 'foo_alternative_root' 使用 memory_size=500
我应该如何实现对对象树的修改?
选项:
我想到了以下选项:
I. 模拟器从数据库加载一个对象树然后修改内存中的对象树.
a) 输入文件通过对象树传递,树中的每个对象检查是否应该修改,如果是,则更改其属性或交换一些子对象.为了能够交换子对象,它必须能够从数据库中加载新的子对象。 (或者这样的新子对象必须在开始时确定并与输入文件一起通过树。)
b) 设置控制器更改整棵树的属性,例如通过反思。它不需要遍历整棵树。它只处理输入文件中给出的一些特定树位置。
II. 模拟器加载完整的数据库并将其复制到内存数据库。它通过使用 SQL 查询调整内存数据库来应用输入文件。在第三步中,它使用 JPA 从修改后的内存数据库中加载对象树。
III. SweepMaster 在原始数据库中创建对象树的许多临时副本 ] 并根据用户输入修改它们。然后它指示模拟器使用那些改编的副本。参数变化完成后,SweepMaster 删除临时文件。
是否有进一步的解决方案?您在执行类似任务时有何经验?
我决定选择选项 I b),我将为可在参数变化中使用的字段引入一些自定义注释,例如
@ParameterPath("foo_root")
@参数("qux_huge")
foo.baa = 5
这将使我可以选择进行内部重构(例如更改字段的名称),而无需直接更改参数变化的输入文件。
设置控制器将遍历输入文件并通过反射搜索相应的注释字段。它还会要求工厂创建应该用作该字段值的对象。最后设置控制器将通过反射设置字段的值。
如果我想为我的参数变体使用具有新类型的附加字段,我将必须注释该字段并为新类型扩展工厂。