在Spring Boot Olingo中处理具有关联关系的实体。

huangapple go评论96阅读模式
英文:

Doing a post on spring boot olingo on an entity with a relationship

问题

我有一些基于 Spring Boot 和 Olingo 构建的 OData V2 API。我正在尝试对具有关联的实体进行发布。

当我尝试使用 CompanyProfileDetails API 进行发布时:

{
    "Version": "1",
    "CompanyProfile": "1"
}

它无法工作,但是这个结构可以工作:

{
    "Version": "1",
    "CompanyProfileDetails": {
		"__metadata": {
            "id": "http://localhost:8080/odata/CompanyProfiles(1L)",
            "uri": "http://localhost:8080/odata/CompanyProfiles(1L)",
            "type": "default.CompanyProfile"
        }
	}
}

所以现在我想知道这是否是使用关联进行发布的 OData 标准,还是是否有一些设置可以接受第一个结构。

另外需要说明的是,第二个数据结构中的 "CompanyProfileDetails" 是 Olingo 自动命名的相关实体。实际上它是 CompanyProfiles 实体。

另一个例子:

public class CompanyProfile {
    // 类定义
}

public class Location {
    // 类定义
}

工作的请求看起来像这样:

{
    "Version": "1",
    "ContactNumber": "1245",
    "Name": "OIL Tycoon corporation",
    "Status": "OK",
    "LocationDetails" : {
		"__metadata": {
            "id": "http://localhost:8080/odata/Locations(2L)",
            "uri": "http://localhost:8080/odata/Locations(2L)",
            "type": "default.Location"
        }
	}
}

然而,这个请求却不工作:

{
    "Version": "1",
    "ContactNumber": "1245",
    "Name": "OIL Tycoon corporation",
    "Status": "OK",
    "Address" : "2"
}

在这个情况下,具有 Id 为 2 的 Location 是存在的。

根据你的要求,这是第二个例子的 $metadata 内容。希望这能帮助你理解!

<EntityType Name="CompanyProfile">
    <!-- 属性和导航属性的定义 -->
</EntityType>
<EntityType Name="Location">
    <!-- 属性和导航属性的定义 -->
</EntityType>
英文:

I have some odata V2 apis built from spring-boot and olingo. I'm trying to a post to an entity with a relationship

public class CompanyProfileDetail {

    private Long id;

    @NotNull
    private Long version;

    @NotNull
    @OneToOne
    @JoinColumn(name = &quot;company_profile_id&quot;, referencedColumnName = &quot;id&quot;)
    private CompanyProfile companyProfile;
...
}

public class CompanyProfile {

    private Long id;
    
    @NotNull
    private Long version;

...
}

So when I try to post this using the CompanyProfileDetails api

{
    &quot;Version&quot;: &quot;1&quot;,
    &quot;CompanyProfile&quot;: &quot;1&quot;
}

it doesn't work but this

{
    &quot;Version&quot;: &quot;1&quot;,
    &quot;CompanyProfileDetails&quot; : {
		&quot;__metadata&quot;: {
                &quot;id&quot;: &quot;http://localhost:8080/odata/CompanyProfiles(1L)&quot;,
                &quot;uri&quot;: &quot;http://localhost:8080/odata/CompanyProfiles(1L)&quot;,
                &quot;type&quot;: &quot;default.CompanyProfile&quot;
            }
	}
}

works. So now I'm wondering if this is an odata standard of posting with relationships or is there some setting that will accept the first structure.

FYI the "CompanyProfileDetails" in the second data structure is how olingo automatically names the related entity. It's actually the CompanyProfiles entity

As another example:

public class CompanyProfile {

    private Long id;
    
    @NotNull
    private Long version;

    @ManyToOne
    @JoinColumn(name = &quot;address&quot;, referencedColumnName = &quot;id&quot;)
    private Location address;

    @Column(name=&quot;contact_number&quot;)
    private String contactNumber;

    @NotNull
    @Column(name=&quot;name&quot;)
    private String name;

    @NotNull
    @Column(name=&quot;status&quot;)
    private String status;
...
}

public class Location {
    
    @Id
    @Column(name = &quot;id&quot;)
    @NotNull
    private Long id;


    private Long version;

    @ManyToOne
    @JoinColumn(name = &quot;city&quot;, referencedColumnName = &quot;id&quot;)
    private CityMunicipality city;

    @ManyToOne
    @JoinColumn(name = &quot;province&quot;, referencedColumnName = &quot;id&quot;)
    private Province province;
}

The working request looks like this:

{
    &quot;Version&quot;: &quot;1&quot;,
    &quot;ContactNumber&quot;: &quot;1245&quot;,
    &quot;Name&quot;: &quot;OIL Tycoon corporation&quot;,
    &quot;Status&quot;: &quot;OK&quot;,
    &quot;LocationDetails&quot; : {
		&quot;__metadata&quot;: {
                &quot;id&quot;: &quot;http://localhost:8080/odata/Locations(2L)&quot;,
                &quot;uri&quot;: &quot;http://localhost:8080/odata/Locations(2L)&quot;,
                &quot;type&quot;: &quot;default.Location&quot;
            }
	}
}

However this does not work:

{
    &quot;Version&quot;: &quot;1&quot;,
    &quot;ContactNumber&quot;: &quot;1245&quot;,
    &quot;Name&quot;: &quot;OIL Tycoon corporation&quot;,
    &quot;Status&quot;: &quot;OK&quot;,
    &quot;Address&quot; : &quot;2&quot;,
}

Location with an Id of 2 exists in this case.

As requested the $metadata. This is for the second example. Hope this helps!

&lt;EntityType Name=&quot;CompanyProfile&quot;&gt;
                &lt;Key&gt;
                    &lt;PropertyRef Name=&quot;Id&quot;&gt;&lt;/PropertyRef&gt;
                &lt;/Key&gt;
                &lt;Property Name=&quot;Address&quot; Type=&quot;Edm.Int64&quot; Nullable=&quot;true&quot;&gt;&lt;/Property&gt;
                &lt;Property Name=&quot;ContactNumber&quot; Type=&quot;Edm.String&quot; Nullable=&quot;true&quot; MaxLength=&quot;255&quot;&gt;&lt;/Property&gt;
                &lt;Property Name=&quot;Id&quot; Type=&quot;Edm.Int64&quot; Nullable=&quot;false&quot;&gt;&lt;/Property&gt;
                &lt;Property Name=&quot;Version&quot; Type=&quot;Edm.Int64&quot;&gt;&lt;/Property&gt;
                &lt;Property Name=&quot;Name&quot; Type=&quot;Edm.String&quot;&gt;&lt;/Property&gt;
                &lt;NavigationProperty Name=&quot;LocationDetails&quot; Relationship=&quot;default.CompanyProfile_Location_Many_ZeroToOne0&quot; FromRole=&quot;CompanyProfile&quot; ToRole=&quot;Location&quot;&gt;&lt;/NavigationProperty&gt;
&lt;/EntityType&gt;
&lt;EntityType Name=&quot;Location&quot;&gt;
                &lt;Key&gt;
                    &lt;PropertyRef Name=&quot;Id&quot;&gt;&lt;/PropertyRef&gt;
                &lt;/Key&gt;
                &lt;Property Name=&quot;City&quot; Type=&quot;Edm.String&quot; Nullable=&quot;true&quot;&gt;&lt;/Property&gt;
                &lt;Property Name=&quot;Id&quot; Type=&quot;Edm.Int64&quot; Nullable=&quot;false&quot;&gt;&lt;/Property&gt;
                &lt;Property Name=&quot;Province&quot; Type=&quot;Edm.String&quot; Nullable=&quot;true&quot;&gt;&lt;/Property&gt;
                &lt;Property Name=&quot;Region&quot; Type=&quot;Edm.Region&quot; Nullable=&quot;true&quot;&gt;&lt;/Property&gt;
                &lt;Property Name=&quot;Version&quot; Type=&quot;Edm.Int64&quot; Nullable=&quot;true&quot;&gt;&lt;/Property&gt;
&lt;/EntityType&gt; 

答案1

得分: 2

默认情况下,Olingo 2.0 JPA处理器的导航属性命名格式为&lt;导航属性名称&gt;Details,因此例如,如果您有一个名为Location的连接,则导航属性将被命名为LocationDetails

要执行DeepInsert,您可以使用以下有效负载:

{
    "version": "1",
    "contactNumber": "",
    "LocationDetails": {
        "id": "",
        "version": "",
        "CityMunicipalityDetails": {
            // 城市类的所有属性
        },
        "ProvinceDetails": {
            // 省份类的所有属性
        }
    }
}

或者您还可以查看OData 2中$batch的实现,因为Deep Insert是OData实现的较新版本的一部分,但是Olingo 2.0 JPA处理器也在2.0版本中实现了。

附注:请检查导航属性名称的$metadata,如果可能的话,请发布$metadata内容,如果此解决方案无法解决问题。

英文:

The Default Implementaion of Olingo 2.0 JPA processor names the Navigation properties in the format &lt;Navigation Property Name&gt;Details , so for example if you have a join named Location the navigation property will be named as LocationDetails

To perform the DeepInset you can use the following payload

{
    &quot;version&quot;: &quot;1&quot;,
    &quot;contactNumber&quot; : &quot;&quot;,
    &quot;LocationDetails&quot;: {
        &quot;id&quot;:&quot;&quot;,
        &quot;version&quot;:&quot;&quot;,
         &quot;CityMunicipalityDetails&quot;:{
             // all attributes of city class
          },
         &quot;ProvinceDetails&quot;:{
            // all attributes of province class
          }
    
    }
}

Alternatively you can also look at the implementation of $batch in OData 2 as Deep inserts were part of Later Version of OData Implementations but Olingo 2.0 JPA Processor implemented in version 2.0 also.

PS: Please check the $metadata for the navigation property names and if possible post the $metadata content if this solution doesn't solves the issue.

答案2

得分: 0

你已经指定了两个不起作用的POST请求。对于第一个请求,下面的请求体应该可以工作。

{
    "version": "1",
    "companyProfile": {
        "id": 1,
        "version": "1"
    }
}

对于第二个请求,

{
    "version": "1",
    "contactNumber": "",
    "address": {
        "id": "",
        "version": "",
        "city": {
            // 城市类的所有属性
        },
        "province": {
            // 省份类的所有属性
        }
    }
}
英文:

You have specified two post request which is not working. For the first one, below request body should work.

{
    &quot;version&quot;: &quot;1&quot;,
    &quot;companyProfile&quot;: {
		&quot;id&quot; : 1,
		&quot;version&quot; : &quot;1&quot;
	
	}
}

For the second one,

{
    &quot;version&quot;: &quot;1&quot;,
    &quot;contactNumber&quot; : &quot;&quot;,
    &quot;address&quot;: {
		&quot;id&quot;:&quot;&quot;,
        &quot;version&quot;:&quot;&quot;,
         &quot;city&quot;:{
             // all attributes of city class
          },
         &quot;province&quot;:{
            // all attributes of province class
          }
	
	}
}

huangapple
  • 本文由 发表于 2020年7月27日 13:48:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63109329.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定