Java 外键不';我不是在写文章,而是在写文章
我在春季使用外键时遇到问题。返回的对象在我的关系上没有正确的值 创建的响应中缺少订单的Java 外键不';我不是在写文章,而是在写文章,java,spring,hibernate,spring-data-jpa,spring-data-rest,Java,Spring,Hibernate,Spring Data Jpa,Spring Data Rest,我在春季使用外键时遇到问题。返回的对象在我的关系上没有正确的值 创建的响应中缺少订单的orderTypeId,但后续GET请求会产生预期结果 预期行为 这里有一个我想要实现的小例子 请求 POST /api/orders { "orderType": "orderTypes/1", } { "id": 2, "orderTypeId": 1, // either this "orderType": "orderTypes/1" // or
orderTypeId
,但后续GET请求会产生预期结果
预期行为
这里有一个我想要实现的小例子
请求
POST /api/orders
{
"orderType": "orderTypes/1",
}
{
"id": 2,
"orderTypeId": 1, // either this
"orderType": "orderTypes/1" // or this
"_links": {
"self": {
"href": "http://localhost:8090/api/orders/2"
},
"order": {
"href": "http://localhost:8090/api/orders/2"
},
"orderType": {
"href": "http://localhost:8090/api/orders/2/orderType"
},
"orderType": {
"href": "orderTypes/1" // this could even be acceptable
}
}
}
{
"id": 2,
"orderTypeId": null,
"_links": {
"self": {
"href": "http://localhost:8090/api/orders/2"
},
"order": {
"href": "http://localhost:8090/api/orders/2"
},
"orderType": {
"href": "http://localhost:8090/api/orders/2/orderType"
}
}
}
或GET/api/orders/2
输出
POST /api/orders
{
"orderType": "orderTypes/1",
}
{
"id": 2,
"orderTypeId": 1, // either this
"orderType": "orderTypes/1" // or this
"_links": {
"self": {
"href": "http://localhost:8090/api/orders/2"
},
"order": {
"href": "http://localhost:8090/api/orders/2"
},
"orderType": {
"href": "http://localhost:8090/api/orders/2/orderType"
},
"orderType": {
"href": "orderTypes/1" // this could even be acceptable
}
}
}
{
"id": 2,
"orderTypeId": null,
"_links": {
"self": {
"href": "http://localhost:8090/api/orders/2"
},
"order": {
"href": "http://localhost:8090/api/orders/2"
},
"orderType": {
"href": "http://localhost:8090/api/orders/2/orderType"
}
}
}
我的代码
实体
@Data
@Entity
public class Order {
@Id
@GeneratedValue
private Long id;
@Column(name = "order_type_id", nullable = false, insertable = false, updatable = false)
private Long orderTypeId;
@NotNull
@ManyToOne
@JoinColumn(name = "order_type_id")
private OrderType orderType;
}
@Data
@Entity
public class OrderType {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@JsonIgnore
@OneToMany(mappedBy = "orderType")
private List<Order> orders;
}
输出
POST /api/orders
{
"orderType": "orderTypes/1",
}
{
"id": 2,
"orderTypeId": 1, // either this
"orderType": "orderTypes/1" // or this
"_links": {
"self": {
"href": "http://localhost:8090/api/orders/2"
},
"order": {
"href": "http://localhost:8090/api/orders/2"
},
"orderType": {
"href": "http://localhost:8090/api/orders/2/orderType"
},
"orderType": {
"href": "orderTypes/1" // this could even be acceptable
}
}
}
{
"id": 2,
"orderTypeId": null,
"_links": {
"self": {
"href": "http://localhost:8090/api/orders/2"
},
"order": {
"href": "http://localhost:8090/api/orders/2"
},
"orderType": {
"href": "http://localhost:8090/api/orders/2/orderType"
}
}
}
但是,如果我执行GET/orders/2
orderTypeId设置正确
我做错了什么
更新 我试过别的东西
@Data
@Entity
public class Order {
@Id
@GeneratedValue
private Long id;
@NotNull
@ManyToOne
@JoinColumn
@JsonManagedReference
@RestResource(exported=false) // ADDED
private OrderType orderType;
}
@Data
@Entity
public class OrderType {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
// removed orders
}
GET/api/orders/2
{
"id": 2,
"orderTypeId": {
"id": 1,
"name": "foo"
},
"_links": {
"self": {
"href": "http://localhost:8090/api/orders/2"
},
"order": {
"href": "http://localhost:8090/api/orders/2"
}
}
}
但现在POST不起作用:(
返回400个错误请求…使用
@JsonIgnore
不是推荐的方法,要管理循环依赖关系,请在实体中使用@JsonManagedReference
。
实体:
@Data
@Entity
public class Order {
@Id
@GeneratedValue
private Long id;
@Column(name = "order_type_id", nullable = false, insertable = false, updatable = false)
private Long orderTypeId;
@JsonBackReference(value="name")
@ManyToOne
@JoinColumn(name = "order_type_id")
private OrderType orderType;
}
@Data
@Entity
public class OrderType {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@JsonManagedReference(value = "name")
@OneToMany(mappedBy = "orderType")
private List<Order> orders;
}
@数据
@实体
公共阶级秩序{
@身份证
@生成值
私人长id;
@列(name=“order\u type\u id”,null=false,insertable=false,updateable=false)
私有长orderTypeId;
@JsonBackReference(value=“name”)
@许多酮
@JoinColumn(name=“订单类型\u id”)
私有OrderType OrderType;
}
@资料
@实体
公共类OrderType{
@身份证
@生成值
私人长id;
@列(nullable=false)
私有字符串名称;
@JsonManagedReference(value=“name”)
@OneToMany(mappedBy=“orderType”)
私人名单订单;
}
现在回答您的问题,PostAPI的返回将不会返回OrderType,因为Hibernate不会将其识别为初始化实体。
您可以稍后在您的案例中执行GET调用,也可以在保存后在POST api中使用rest控制器。您可以在返回之前按id执行GET调用,或者使用DTO发送响应。使用
@JsonIgnore
不是推荐的方法,要管理循环依赖关系,请在您的应用程序中使用@JsonManagedReference
实体。
实体:
@Data
@Entity
public class Order {
@Id
@GeneratedValue
private Long id;
@Column(name = "order_type_id", nullable = false, insertable = false, updatable = false)
private Long orderTypeId;
@JsonBackReference(value="name")
@ManyToOne
@JoinColumn(name = "order_type_id")
private OrderType orderType;
}
@Data
@Entity
public class OrderType {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@JsonManagedReference(value = "name")
@OneToMany(mappedBy = "orderType")
private List<Order> orders;
}
@数据
@实体
公共阶级秩序{
@身份证
@生成值
私人长id;
@列(name=“order\u type\u id”,null=false,insertable=false,updateable=false)
私有长orderTypeId;
@JsonBackReference(value=“name”)
@许多酮
@JoinColumn(name=“订单类型\u id”)
私有OrderType OrderType;
}
@资料
@实体
公共类OrderType{
@身份证
@生成值
私人长id;
@列(nullable=false)
私有字符串名称;
@JsonManagedReference(value=“name”)
@OneToMany(mappedBy=“orderType”)
私人名单订单;
}
现在回答您的问题,PostAPI的返回将不会返回OrderType,因为Hibernate不会将其识别为初始化实体。
您可以稍后在您的案例中执行GET调用,也可以在保存后在POST api中使用rest控制器。您可以在返回之前按id执行GET调用,或者使用DTO发送响应。问题是,在构造新实例时,即作为POST请求的结果,将不会填充此字段。但是,它将e作为对GET请求的响应而填充,即,由于字段上的JPA注释,它将由Hibernate填充 我不太清楚为什么需要将其映射为持久字段。简单地添加一个getter应该意味着它包含在任何JSON响应中:
@Data
@Entity
public class Order {
@Id
@GeneratedValue
private Long id;
@NotNull
@ManyToOne
@JoinColumn(name = "order_type_id")
private OrderType orderType;
public Long getOrderTypeId(){
return orderType != null ? orderType.getId() : null;
}
}
未能为AfterCreateEvent添加侦听器
并根据关联的OrderType
在此侦听器上手动设置值,或者向侦听器注入EntityManager
,并在保存的实例上触发刷新:
问题是,在构造新实例时,即作为POST请求的结果,此字段将不会填充。但是,它将作为GET请求的响应而填充,即作为字段上JPA注释的结果,它将由Hibernate填充
我不太清楚为什么需要将其映射为持久字段。简单地添加一个getter应该意味着它包含在任何JSON响应中:
@Data
@Entity
public class Order {
@Id
@GeneratedValue
private Long id;
@NotNull
@ManyToOne
@JoinColumn(name = "order_type_id")
private OrderType orderType;
public Long getOrderTypeId(){
return orderType != null ? orderType.getId() : null;
}
}
未能为AfterCreateEvent添加侦听器
并根据关联的OrderType
在此侦听器上手动设置值,或者向侦听器注入EntityManager
,并在保存的实例上触发刷新:
删除JsonIgnore并查看JsonManagedReference和JsonBackReference注释。通常实体不会在REST API中返回。使用DTOsremove JsonIgnore并查看JsonManagedReference和JsonBackReference注释。通常实体不会在REST API中返回。使用DTOsThanks突出显示@JsonIgnore
是sue.我改变了这一点。所以现在我必须为我的@RepositoryRestResource
设置DTO。你在这方面有什么好的资源吗?我想避免手动实现控制器,并继续使用“开箱即用”解决方案感谢@JoinColumn(name=“order\u type\u id”)
这对我帮助很大。我想在订单表的回复中包含fk_id,并尝试了很多东西,因为我对Spring非常陌生。感谢你突出显示了@JsonIgnore
问题。我改变了这一点。所以现在我必须为我的@RepositoryRestResource
设置DTO。你在这方面有什么好的资源吗?我想避免ha正在手动实施控制器并继续使用“简易开箱即用”解决方案感谢@JoinColumn(name=“order\u type\u id”)
这对我帮助很大。我希望在订单表的响应中包含fk_id,并尝试了很多东西,因为我对Spring非常陌生。仅添加该方法就会导致此错误无法在此ManagedType[com.demo.m]上找到具有给定名称[orderTypeId]的属性