简体   繁体   English

休眠数据映射到子对象

[英]Hibernate data mapping into child objects

I'm trying to figure out how to map data coming in on a request to a Hibernate object, and the issue is that the data coming in could be on the object or the child objects, and the field data is not necessarily known - the forms are user configured to contain and collect the desired data. 我试图弄清楚如何将请求中传入的数据映射到Hibernate对象,问题是传入的数据可以在对象或子对象上,而字段数据不一定是已知的-用户配置表格以包含和收集所需的数据。

Roughly, the objects are like this: 大致来说,对象是这样的:

Job {
  String title;

  @ManyToOne
  @JoinColumn(name = "location_id")
  JobLocation location;
}

JobLocation {
  int id;
  String description;
  double latitude;
  double longitude;
}

So if the user has defined that they want to edit the JobLocation description, we will get back in the request something along the lines of 因此,如果用户定义了他们想要编辑JobLocation描述,我们将在请求中返回类似以下内容的内容:

{ jobLocationDescription: 'Santa Fe' }

How does that get mapped back to the child of the Job I'm dealing with? 如何将其映射回我正在处理的Job的子级? All I have at save time is the reference to the Job , all other items could be varying depending on what they have selected in dropdowns, etc. One option is to store a reference such as job.location.description , and have getters and use reflection to do a process-driving option: 在保存时,我所拥有的只是对Job的引用,所有其他项目可能会有所不同,具体取决于它们在下拉菜单中选择的内容,等等。一种选择是存储诸如job.location.description的引用,并具有getter和use反思做一个过程驱动选项:

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);

Sadly, there is nothing saying it couldn't be multiple levels, and to get the methods we are currently thinking we would have to use reflection. 可悲的是,没有什么可以说它不可能是多个级别的,要获得我们目前认为的方法,我们必须使用反射。 Are there other, better ways to do this type of operation or do we just have to slog through this? 还有其他更好的方法来进行此类操作吗?还是我们只需要克服这种麻烦?

I had almost similar type of requirement in our project. 在我们的项目中,我有几乎类似的需求类型。 We ended up using the reflection + annotation for mapping. 我们最终使用了反射+注释进行映射。 On a nutshell, we were having something like this to construct the object. 简而言之,我们正在使用类似的东西来构造对象。

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;
}

If you haven't got what I mean, we created custom annotation and we wrote a utility method that via reflection loops through the elements that has annotations as follows: 如果您没有理解我的意思,我们创建了自定义注释,并编写了一个实用程序方法,该方法通过反射遍历具有注释的元素,如下所示:

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.
   }
}

If you know at compile time the name of the method you're calling, you don't have to use reflection. 如果在编译时知道要调用的方法的名称,则不必使用反射。 It sounds like you need reflection. 听起来您需要反思。 However, that doesn't mean you have to use the raw java.lang.reflect API, which is pretty painful to use directly. 但是,这并不意味着您必须使用原始的java.lang.reflect API,直接使用它非常痛苦。 If you're already using Spring, BeanWrapperImpl is a very nice utility that can use your existing ConversionService to convert your input to the target type. 如果您已经在使用Spring,那么BeanWrapperImpl是一个非常不错的实用程序,可以使用您现有的ConversionService将您的输入ConversionService为目标类型。 Otherwise I'd suggest Commons BeanUtils , which does pretty much the same thing without the Springiness. 否则,我建议使用Commons BeanUtils ,它在没有弹性的情况下可以做几乎相同的事情。 Both libraries know how to handle nested properties and Map -valued properties as well. 这两个库都知道如何处理嵌套属性和Map值属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM