Jpa級聯(lián)操作
級聯(lián)web
記JPA一個問題,Multiple representations of the same entity [XXX#1] are being merged.
實體關(guān)系之@OneToMany
博客分類: hibernate & ejb
SQL
Order.java
Java代碼 收藏代碼
package com.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name = "Orders")
public class Order implements Serializable {
private Integer orderid;//訂單號
private Float amount;//訂單金額
private Set<OrderItem> orderItems = new HashSet<OrderItem>();//訂單項
private Date createdate;//訂單創(chuàng)建日期
@Id
@GeneratedValue
public Integer getOrderid() {
return orderid;
}
public void setOrderid(Integer orderid) {
this.orderid = orderid;
}
@Column(name="amount")//name: 映射的列名,如果不指定映射列名,容器默認將屬性名稱作為的映射的數(shù)據(jù)庫表列名塞琼。
public Float getAmount() {
return amount;
}
public void setAmount(Float amount) {
this.amount = amount;
}
/*
* @OneToMany: 指明Order 與OrderItem關(guān)聯(lián)關(guān)系為一對多關(guān)系
*
* mappedBy: 定義類之間的雙向關(guān)系董济。如果類之間是單向關(guān)系,不需要提供定義灰追,如果類和類之間形成雙向關(guān)系闪金,我們就需要使用這個屬性進行定義叼屠,
* 否則可能引起數(shù)據(jù)一致性的問題瞳腌。
*
* cascade: CascadeType[]類型。該屬性定義類和類之間的級聯(lián)關(guān)系镜雨。定義的級聯(lián)關(guān)系將被容器視為對當前類對象及其關(guān)聯(lián)類對象采取相同的操作嫂侍,
* 而且這種關(guān)系是遞歸調(diào)用的。舉個例子:Order 和OrderItem有級聯(lián)關(guān)系荚坞,那么刪除Order 時將同時刪除它所對應的OrderItem對象挑宠。
* 而如果OrderItem還和其他的對象之間有級聯(lián)關(guān)系,那么這樣的操作會一直遞歸執(zhí)行下去颓影。cascade的值只能從CascadeType.PERSIST(級聯(lián)新建)各淀、
* CascadeType.REMOVE(級聯(lián)刪除)、CascadeType.REFRESH(級聯(lián)刷新)诡挂、CascadeType.MERGE(級聯(lián)更新)中選擇一個或多個碎浇。
* 還有一個選擇是使用CascadeType.ALL,表示選擇全部四項璃俗。
*
* fatch: 可選擇項包括:FetchType.EAGER 和FetchType.LAZY奴璃。前者表示關(guān)系類(本例是OrderItem類)在主類(本例是Order類)加載的時候
* 同時加載;后者表示關(guān)系類在被訪問時才加載,默認值是FetchType. LAZY。
*
*/
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@OrderBy(value = "id ASC")//注釋指明加載OrderItem時按id的升序排序
public Set<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(Set<OrderItem> orderItems) {
this.orderItems = orderItems;
}
//@Temporal注釋用來指定java.util.Date 或java.util.Calendar 屬性與數(shù)據(jù)庫類型date,time 或timestamp 中的那一種類型進行映射
@Temporal(value = TemporalType.TIMESTAMP)
public Date getCreatedate() {
return createdate;
}
public void setCreatedate(Date createdate) {
this.createdate = createdate;
}
/*
* 添加訂單
*/
public void addOrderItem(OrderItem orderitem) {
if (!this.orderItems.contains(orderitem)) {
this.orderItems.add(orderitem);
orderitem.setOrder(this);
}
}
/*
* 刪除訂單
*/
public void removeOrderItem(OrderItem orderitem) {
orderitem.setOrder(null);
this.orderItems.remove(orderitem);
}
}
OrderItem.java
Java代碼 收藏代碼
package com.entity;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "OrderItems")//name = "OrderItems"城豁,表示本實體對應數(shù)據(jù)庫表 OrderItems苟穆,可選。
public class OrderItem implements Serializable {
private Integer id;//作為主鍵
private String productname;//產(chǎn)品名稱
private Float price;//價格
private Order order;//對應的訂單
/*
* 無參數(shù)構(gòu)造器可別忘了
*/
public OrderItem() {
}
/*
* 帶參數(shù)的構(gòu)造器唱星,用于初始化實例變量
*/
public OrderItem(String productname, Float price) {
this.productname = productname;
this.price = price;
}
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="productname")
public String getProductname() {
return productname;
}
public void setProductname(String productname) {
this.productname = productname;
}
@Column(name="price")
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
/*
* @ManyToOne指明OrderItem和Order之間為多對一關(guān)系雳旅,多個OrderItem實例關(guān)聯(lián)的都是同一個Order對象。
* 其中的屬性和@OneToMany基本一樣间聊,但@ManyToOne注釋的fetch屬性默認值是FetchType.EAGER岭辣。
*
* optional 屬性是定義該關(guān)聯(lián)類對是否必須存在,值為false時甸饱,關(guān)聯(lián)類雙方都必須存在沦童,如果關(guān)系被維護端不存在,查詢的結(jié)果為null叹话。
* 值為true 時, 關(guān)系被維護端可以不存在偷遗,查詢的結(jié)果仍然會返回關(guān)系維護端,在關(guān)系維護端中指向關(guān)系被維護端的屬性為null驼壶。
* optional 屬性的默認值是true氏豌。舉個例:某項訂單(Order)中沒有訂單項(OrderItem),如果optional 屬性設(shè)置為false热凹,
* 獲取該項訂單(Order)時泵喘,得到的結(jié)果為null泪电,如果optional 屬性設(shè)置為true,仍然可以獲取該項訂單纪铺,但訂單中指向訂單項的屬性為null相速。
* 實際上在解釋Order 與OrderItem的關(guān)系成SQL時,optional 屬性指定了他們的聯(lián)接關(guān)系optional=false聯(lián)接關(guān)系為inner join,
* optional=true聯(lián)接關(guān)系為left join鲜锚。
*
* @JoinColumn:指明了被維護端(OrderItem)的外鍵字段為order_id突诬,它和維護端的主鍵(orderid)連接,unique= true 指明order_id列的值不可重復。
*/
@ManyToOne(cascade = CascadeType.REFRESH, optional = false)
@JoinColumn(name = "order_id",referencedColumnName="orderid")
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
}
Java你會用芜繁,但這10點實戰(zhàn)經(jīng)驗你一定不知道旺隙!