OData CRUD (V2) - CREATE 操作完全解析
在 OData 服务中,CREATE 操作允许客户端通过 HTTP POST 请求向服务端添加新数据,是除查询(Query)之外最常用的写操作之一。本文将深入讲解 OData V2 中 CREATE 的实现方式、核心方法
CREATE_ENTITY的用法,以及深度创建、事务处理等相关知识。
一、CREATE 操作概述
1.1 什么是 CREATE?
| 维度 | 说明 |
|---|---|
| HTTP 方法 | POST |
| URL 示例 | /sap/opu/odata/SAP/ZXKJ_USER_SRV/ZUSERSet |
| 请求体 | 新实体的数据(JSON / XML / Atom) |
| 响应 | 创建后的完整实体(含服务端生成的字段,如 ID),状态码 201 Created |
| 同步性 | 默认同步,服务端处理完即返回结果 |
二、实现 CREATE_ENTITY 方法完成ODATA CURD之Create功能
回顾:当通过 SEGW 事务码创建一个 OData 项目并生成运行时对象后,系统会自动产生两对类:MPC、MPC_EXT 和 DPC、DPC_EXT

不同于Query的是,Create 必须手动实现, 方法是重写 Runtime Artifacts下
DPC_EXT类中的方法:<EntitySet>_CREATE_ENTITY。为什么重写 Runtime Artifacts 下的类方法就能实现 Service Implementation的CRUD?
那可以扒一扒ODATA架构下两个重要组成部分的联系。
Runtime Artifacts 与 Service Implementation 的关系:
概念 定义 来源 作用 Runtime Artifacts SEGW 生成的所有运行时对象的统称(MPC、DPC、 *_EXT类、服务注册等)自动生成 提供 OData 服务的"骨架":固定了请求与方法的映射、元数据、数据结构 Service Implementation 开发者在 DPC_EXT和MPC_EXT中编写的业务逻辑代码手动编写 填充"血肉":具体的数据读取、插入、更新、删除操作 一个通俗的类比:
Runtime Artifacts = 一台自动售货机的外壳和投币口(固定了"投币后商品会掉下来"的流程)。
DPC_EXT 重写 = 您在机器内部放入具体的饮料(决定掉下来的是可乐还是矿泉水)。
Service Implementation CRUD 实现 = 顾客投币后,就能拿到您放进去的饮料。
没有外壳(Runtime Artifacts),饮料无处安放;没有您放入的饮料(Service Implementation),机器只出空瓶。
重写 Runtime Artifacts 下类的方法之所以能实现 CRUD,是因为 SAP Gateway 运行时框架会通过面向对象的多态性,自动调用子类(DPC_EXT)中重写后的方法。父类 DPC 提供了固定的请求处理入口,而子类中您编写的代码就是实际完成数据库增删改查的业务逻辑。
2.1 类的作用
| 类的作用 | 一句话总结 |
|---|---|
| MPC | 存放静态模型定义,每次生成都会被覆盖,不要手动修改。 |
| MPC_EXT | 用于动态调整元数据,一般不需改动 CREATE 相关逻辑。 |
| DPC | 存放所有操作的骨架方法(包括 CREATE),默认没有实现写逻辑,不要手动修改。 |
| DPC_EXT | 开发者唯一的工作区 ,必须在此手动重写 *_CREATE_ENTITY(以及 UPDATE/DELETE),实现真正的数据写入。 |
2.2 最简实现示例
假设我们有一个数据库表 ZKJUSER

表结构如下:
| 字段名 | 类型 | 长度 |
|---|---|---|
| MANDT | CLNT | 3 |
| ID | INT1 | 3 |
| NAME | CHAR | 10 |
| ADDRESS | CHAR | 20 |
创建发布ODATA Service 后对自动生成DPC_EXT 类的方法CREATE_ENTITY重写


CREATE_ENTITY 代码:
METHOD zuserset_create_entity.
DATA: ls_user TYPE zkjuser. " 数据库表结构
" 1. 从请求体中读取传入的学生数据
io_data_provider->read_entry_data(
IMPORTING
es_data = ls_user
).
MODIFY zkjuser FROM ls_user.
ENDMETHOD.
激活类后去SAP Gateway Client测试
示例:

Create 操作的关键要素:
| 组成部分 | 说明 |
|---|---|
| HTTP 方法 | POST |
| 请求 URL | 实体集路径:/sap/opu/odata/SAP/ZXKJ_USER_SRV/ZUSERSet |
| 必须请求头 | - X-CSRF-Token:有效 token(如 NgwM6SNGs-5ouXhpsrdI6Q==) - Content-Type: application/atom+xml;type=entry; charset=utf-8 - Accept: application/atom+xml(建议添加) |
| 请求体格式 | Atom/XML entry,包含 <content> 中的 <m:properties> |
| 成功响应 | - 状态码 201 Created - Location 头:新资源的 URL - 响应体:新创建的完整 entry(可能包含服务端生成的字段) |
请求体xml
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<title type="text">ZUSERSet</title>
<updated>2026-04-26T12:00:00Z</updated>
<author><name/></author>
<category term="ZXKJ_USER_SRV.ZUSER"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<content type="application/xml">
<m:properties>
<d:Id>6</d:Id>
<d:Name>Jrey</d:Name>
<d:Address>北京市朝阳区</d:Address>
</m:properties>
</content>
</entry>
三、常见问题与最佳实践
❌ 常见错误1:忘记返回 er_entity
-
现象 :客户端收到
204 No Content,无法获取服务端生成的字段(如主键)。 -
解决 :
CREATE_ENTITY方法最后必须给er_entity赋值。
❌ 常见错误2:直接修改 DPC 类
-
现象:重新生成服务后代码丢失。
-
解决 :始终在 DPC_EXT 中重写方法。
❌ 常见错误3:未做唯一性校验
-
现象 :数据库报主键冲突,服务返回
500 Internal Server Error,客户端无法区分。 -
解决:插入前先检查是否已存在,并抛出友好的业务异常。
✅ 最佳实践清单
四、总结
| 方面 | 要点 |
|---|---|
| 核心方法 | <EntitySet>_CREATE_ENTITY(在 DPC_EXT 中重写) |
| 必须做的事 | 1. 从 io_data_provider 读取数据 2. 执行业务校验 3. 保存到数据库 4. 返回 er_entity |
| 可选增强 | 深度创建(CREATE_DEEP_ENTITY)、自定义主键生成、ETag 乐观锁 |
| 客户端要求 | POST 请求 + 新实体的完整或部分数据 |
记住 :CREATE 是写操作中最基础的一步。掌握了它,UPDATE、DELETE 也会触类旁通。下一篇我们将讲解 UPDATE (PUT/PATCH) 和 DELETE 的实现细节。