Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.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 RequestMapping无法填充EmbeddedId中包含字段的实体类_Java_Spring_Hibernate_Spring Mvc_Spring Data - Fatal编程技术网

Java RequestMapping无法填充EmbeddedId中包含字段的实体类

Java RequestMapping无法填充EmbeddedId中包含字段的实体类,java,spring,hibernate,spring-mvc,spring-data,Java,Spring,Hibernate,Spring Mvc,Spring Data,我有以下实体类: @Entity @Table(name="reporteddevicedata", schema="schemaName") public class MobileDeviceData { @EmbeddedId MobileDeviceDataId mobileDeviceDataId; @Column(name="activitydetecteddate") private ZonedDateTime activityDetectedD

我有以下实体类:

@Entity
@Table(name="reporteddevicedata", schema="schemaName")
public class MobileDeviceData {

    @EmbeddedId 
    MobileDeviceDataId mobileDeviceDataId;

    @Column(name="activitydetecteddate")
    private ZonedDateTime activityDetectedDate;

    public void setFlagId(int flagId) {
        mobileDeviceDataId.setFlagId(flagId);
    }

    ......
}

@Embeddable
class MobileDeviceDataId implements Serializable {
    @Column(name="clientid")
    private int clientId;

    @Column(name="flagid")
    private int flagId;
}
我的
控制器
代码如下所示:

@RequestMapping(value="/mobile/device", method = RequestMethod.PUT)
public ResponseEntity<Object> flagDevice (@RequestBody List<MobileDeviceData> deviceInfoList) {
    // code here
}
@RequestMapping(value=“/mobile/device”,method=RequestMethod.PUT)
公共响应属性flagDevice(@RequestBody列表设备信息列表){
//代码在这里
}
最初,我在
clientId
上使用了我的
Entity
类,它只有一个主键
@ID
,效果非常好。我将进行一个REST调用,它将按照预期填充MobileDeviceData类。然后我使用
@embeddeble
@embeddedableid
注释切换到复合ID,现在
@RequestMapping
无法填充
flagId
参数。现在,当我进行REST调用时,我得到了
mobiledevicedaitaid
的空指针异常,因此当调用该字段并抛出空指针异常时,它无法更新该字段


所以我的问题是,如何获得
@embeddeble
类的实例?我可以用
新建
创建一个吗?我不确定这意味着什么,因为Spring可能希望自己创造这个价值?通过
RequestMapping
更新此字段的“正常”方式是什么?

首先,您应该避免嵌入id,这只会让所有事情变得更加困难

代理主键更容易使用,当您在具有多列主键的表上有外键时,它会使处理变得更加复杂

现在你自己面对这些问题,但是根据你的问题

@RequestMapping(value="/mobile/device", method = RequestMethod.PUT)
public ResponseEntity<Object> flagDevice (@RequestBody List<MobileDeviceData> deviceInfoList) {
    for(MobileDeviceData mobileDeviceData : deviceInfoList){
        int clientId = mobileDeviceData.getMobileDeviceDataId().getClientId();
        int flagId = mobileDeviceData.getMobileDeviceDataId().getFlagId();
        MobileDeviceData foundMobileDeviceData = mobileDeviceDataService.findByClientIdAndFlagId(clientId, flagId);
        if(foundMovileDeviceData == null){
            mobileDeviceDataService.save(mobileDeviceData);
        }else {
            //update foundMobileDeviceData with mobileDeviceData  fields
            mobileDeviceDataService.save(foundMobileDeviceData);
        }
    }
}
或本机sql

"SELECT * FROM reporteddevicedata WHERE client_id = :someParam"
JSON请求示例

[ {
  "mobileDeviceDataId" : {
    "clientId" : 0,
    "flagId" : 0
  },
  "activityDetectedDate" : null
}, {
  "mobileDeviceDataId" : {
    "clientId" : 1,
    "flagId" : 1
  },
  "activityDetectedDate" : null
}, {
  "mobileDeviceDataId" : {
    "clientId" : 2,
    "flagId" : 2
  },
  "activityDetectedDate" : null
} ]
uglified准备复制/粘贴版本:

[{"mobileDeviceDataId":{"clientId":0,"flagId":3},"activityDetectedDate":null},{"mobileDeviceDataId":{"clientId":1,"flagId":1},"activityDetectedDate":null},{"mobileDeviceDataId":{"clientId":2,"flagId":2},"activityDetectedDate":null}]
另外,应该在MobileData对象上添加一些验证,以避免在发送无效json请求时出现空指针(不存在mobileDeviceDataId)

最后回答问题:

使用数据库模型作为API之间共享的容器被认为不是一个好的做法(因为主键,可能是一些敏感数据,这取决于)

此外,如果您想让EmbeddeBleid工作,则必须像示例json中那样构建请求。必须填写适当的字段。当请求不是以这种方式构建的,它们只是没有“嵌入id”的平面json时,您必须创建一些适合json格式的包装(该包装将是requestbody类或列表)。接下来,您必须将包装器转换为具有嵌入id(使用新关键字创建)的db对象。
这就是为什么我建议您不要使用复合id或嵌入式id。这是一个简单的示例,您只有一个表,但当涉及到使用外键和多列主键时,选项卡变得更加复杂和混乱,这就是为什么我建议您使用代理id而不嵌入任何内容,这会使事情变得更困难,而且很混乱。首先,您应该避免嵌入id,这会使所有事情变得更困难

代理主键更容易使用,当您在具有多列主键的表上有外键时,它会使处理变得更加复杂

现在你自己面对这些问题,但是根据你的问题

@RequestMapping(value="/mobile/device", method = RequestMethod.PUT)
public ResponseEntity<Object> flagDevice (@RequestBody List<MobileDeviceData> deviceInfoList) {
    for(MobileDeviceData mobileDeviceData : deviceInfoList){
        int clientId = mobileDeviceData.getMobileDeviceDataId().getClientId();
        int flagId = mobileDeviceData.getMobileDeviceDataId().getFlagId();
        MobileDeviceData foundMobileDeviceData = mobileDeviceDataService.findByClientIdAndFlagId(clientId, flagId);
        if(foundMovileDeviceData == null){
            mobileDeviceDataService.save(mobileDeviceData);
        }else {
            //update foundMobileDeviceData with mobileDeviceData  fields
            mobileDeviceDataService.save(foundMobileDeviceData);
        }
    }
}
或本机sql

"SELECT * FROM reporteddevicedata WHERE client_id = :someParam"
JSON请求示例

[ {
  "mobileDeviceDataId" : {
    "clientId" : 0,
    "flagId" : 0
  },
  "activityDetectedDate" : null
}, {
  "mobileDeviceDataId" : {
    "clientId" : 1,
    "flagId" : 1
  },
  "activityDetectedDate" : null
}, {
  "mobileDeviceDataId" : {
    "clientId" : 2,
    "flagId" : 2
  },
  "activityDetectedDate" : null
} ]
uglified准备复制/粘贴版本:

[{"mobileDeviceDataId":{"clientId":0,"flagId":3},"activityDetectedDate":null},{"mobileDeviceDataId":{"clientId":1,"flagId":1},"activityDetectedDate":null},{"mobileDeviceDataId":{"clientId":2,"flagId":2},"activityDetectedDate":null}]
另外,应该在MobileData对象上添加一些验证,以避免在发送无效json请求时出现空指针(不存在mobileDeviceDataId)

最后回答问题:

使用数据库模型作为API之间共享的容器被认为不是一个好的做法(因为主键,可能是一些敏感数据,这取决于)

此外,如果您想让EmbeddeBleid工作,则必须像示例json中那样构建请求。必须填写适当的字段。当请求不是以这种方式构建的,它们只是没有“嵌入id”的平面json时,您必须创建一些适合json格式的包装(该包装将是requestbody类或列表)。接下来,您必须将包装器转换为具有嵌入id(使用新关键字创建)的db对象。
这就是为什么我建议您不要使用复合id或嵌入式id。这是一个简单的示例,您只有一个表,但当涉及到使用外键和多列主键时,选项卡变得更加复杂和混乱,您使得在db上搜索变得更加困难,这就是为什么我建议您使用代理id而不嵌入任何内容,这会使事情变得更加困难,而且非常混乱

您的错误显示在哪里?在您尝试放置数据时是否会发生这种情况?添加一些您发送的示例requestbody,然后我可能会帮助您了解它out@OskarDajnowicz-我已经更新了问题。将Spring日志设置为debug向我显示了错误是什么。所以现在我只想知道如何更新可嵌入类中的字段的预期方法或“最佳实践”。您的错误显示在哪里?在您尝试放置数据时是否会发生这种情况?添加一些您发送的示例requestbody,然后我可能会帮助您了解它out@OskarDajnowicz-我已经更新了问题。将Spring日志设置为debug向我显示了错误是什么。所以现在我想知道如何更新可嵌入类中的字段的预期方法或“最佳实践”。我想这是对您的问题的回答,还是我仍然遗漏了什么?我想这是对您的问题的回答,还是我仍然遗漏了什么?