无法在休眠状态下保存实体
Posted
技术标签:
【中文标题】无法在休眠状态下保存实体【英文标题】:Can't save entity in hibernate 【发布时间】:2018-11-06 13:04:10 【问题描述】:我创建了简单的 CRUD 服务。有 4 个实体:客户、提供商、产品、交易。
Customer
和 Provider
实体组成了具有以下结构的 id AppId
:
@Getter
@Setter
@Embeddable
@NoArgsConstructor
public class AppId implements Serializable
private String app;
private String id;
//...
这是我想要的业务逻辑:
Providers 实体级联并创建 Product 实体。
当客户与提供商交易时,我需要创建实体Deal
,它不会级联任何其他实体。
它只有涉及供应商、客户和交易产品的字段。
我创建了一些提供商和客户。
然后我尝试创建交易,但我得到了字段客户和提供商null
。
这是我的实体定义:
Provider
:
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@Table(name = "provider")
public class Provider implements Serializable
@EmbeddedId
@Column(name = "appid")
private AppId appId;
@Column(name = "name")
private String name;
@Column(name = "firstname")
private String firstName;
@Column(name = "lastname")
private String lastName;
@Column(name = "latitude")
private float latitude;
@Column(name = "longitude")
private float longitude;
@Column(name = "work_date")
private Date workDate;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "provider_product"
, joinColumns =
@JoinColumn(name = "provider_app"),
@JoinColumn(name = "provider_id")
, inverseJoinColumns = @JoinColumn(name="product_id"))
private Set<Product> products;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumns(
@JoinColumn(name = "app", referencedColumnName = "app", updatable = false, insertable = false),
@JoinColumn(name = "id", referencedColumnName = "id", updatable = false, insertable = false)
)
private List<Deal> dealList = new ArrayList<>();
Customer
:
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@Table(name = "customer")
public class Customer implements Serializable
@EmbeddedId
@Column(name = "appid")
private AppId appId;
@Column(name = "firstname")
private String firstName;
@Column(name = "lastname")
private String lastName;
public Customer(AppId appId, String firstName, String lastName)
this.appId = appId;
this.firstName = firstName;
this.lastName = lastName;
Product
:
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@Table(name = "product")
public class Product implements Serializable
@Id
@GeneratedValue
private long id;
@Column(name = "name")
private String name;
@Column(name = "cost")
private long cost;
Deal
:
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@Table(name = "deal")
public class Deal implements Serializable
@Id
@GeneratedValue
private long id;
@ManyToOne
@JoinColumns(
@JoinColumn(name = "provider_app", referencedColumnName = "app", insertable = false, updatable = false),
@JoinColumn(name = "provider_id", referencedColumnName = "id", insertable = false, updatable = false)
)
private Provider provider;
@ManyToOne
@JoinColumns(
@JoinColumn(name = "customer_app", insertable = false, updatable = false),
@JoinColumn(name = "customer_id", insertable = false, updatable = false)
)
private Customer customer;
@ManyToMany
@JoinTable(name = "deal_product"
, joinColumns = @JoinColumn(name="deal_id", insertable = false, updatable = false)
, inverseJoinColumns = @JoinColumn(name="product_id", insertable = false, updatable = false))
private Set<Product> product;
// deal is complete when provider entered deal id
@Column(name = "closed")
private boolean closed = false;
【问题讨论】:
为什么insertable = false
在Deal
实体中有provider
和customer
字段?
@harsh 因为在创建 deal
实体时,您无法创建新的 provider
或 customer
。 deal
只有在之前创建了provider
和customer
时才能创建。
请分享您创建和保存交易的代码,不看就很难说什么
@harsh 项目链接:github.com/oybek/shavuha-CRUD/tree/master/src/main/java/com/…
【参考方案1】:
通过删除customer
和provider
实体中provider
字段的insertable = false
,一切正常。
"id": 5,
"provider":
"appId":
"app": "vk",
"id": "123"
,
"name": null,
"firstName": null,
"lastName": null,
"latitude": 0,
"longitude": 0,
"workDate": null,
"products": null,
"dealList": []
,
"customer":
"appId":
"app": "vk",
"id": "123"
,
"firstName": null,
"lastName": null
,
"product": [
"id": 2,
"name": "Temp",
"cost": 100
],
"closed": false
我可以得到以下响应。
insertable = false
在字段上意味着当您保存实体时,您不会保存该字段的值,而是会在某处显式设置该字段。
insertable = true
并不意味着您将创建一个新的Customer
或Provider
,由CascadeType
处理
【讨论】:
它在创建不正确的交易时重写提供者实体以上是关于无法在休眠状态下保存实体的主要内容,如果未能解决你的问题,请参考以下文章