我正在试图弄清楚如何将请求中的数据映射到Hibernate对象,问题是进入的数据可能在对象或子对象上,并且字段数据不一定已知 - 表单是用户配置为包含和收集所需数据。
粗略地说,对象是这样的:
Job {
String title;
@ManyToOne
@JoinColumn(name = "location_id")
JobLocation location;
}
JobLocation {
int id;
String description;
double latitude;
double longitude;
}
因此,如果用户已经定义了他们想要编辑JobLocation描述,我们将在请求中返回
的内容。{ jobLocationDescription: 'Santa Fe' }
如何将其映射回我正在处理的Job
的孩子?我在节省时间的所有内容都是对Job
的引用,所有其他项目可能会有所不同,具体取决于他们在下拉列表中选择的内容等。一个选项是存储引用,例如job.location.description
,和有吸气剂并使用反射来做一个过程驱动选项:
String[] field = requestField.split(".");
Entity ent = (get object from field[0]);
if (field.length > 2) {
ent = ent.get[get method name from next field position]();
}
ent.set[get method name from last field[] value](requestValue);
可悲的是,没有什么可以说它不能是多个级别,并且为了获得我们目前认为必须使用反射的方法。是否有其他更好的方法来进行此类操作,或者我们只是不得不勉强通过这个?
答案 0 :(得分:5)
我的项目中几乎有类似的要求。我们最终使用了反射+注释进行映射。简而言之,我们有这样的东西来构建对象。
class Job {
String title;
@ManyToOne
@JoinColumn(name = "location_id")
@EntityMapper(isRef="true")//Custom Annotation
JobLocation location;
}
class JobLocation {
@EntityMapper(fieldName="jobLocationId")
int id;
@EntityMapper(fieldName="jobLocationDescription")//Custom Annotation
String description;
double latitude;
double longitude;
}
如果你没有我的意思,我们创建了自定义注释,我们编写了一个实用工具方法,通过反射循环遍历注释的元素如下:
for (Field field : object.getClass().getDeclaredFields()) {
//check for the EntityMapper annotation
if (field.getAnnotation(EntityMapper.class) != null) {
.
.
.//Use more reflection to use getters and setters to create and assign values from the JSON request.
}
}
答案 1 :(得分:0)
如果您在编译时知道要调用的方法的名称,则不必使用反射。听起来你需要反思。但是,这并不意味着您必须使用原始java.lang.reflect
API,这是非常痛苦的直接使用。如果您已经在使用Spring,BeanWrapperImpl
是一个非常好的实用程序,可以使用现有的ConversionService
将您的输入转换为目标类型。否则,我建议Commons BeanUtils,如果没有弹性,它会做同样的事情。两个库都知道如何处理嵌套属性和Map
- 值属性。