Jpa级联操作
级联web
记JPA一个问题,Multiple representations of the same entity [XXX#1] are being merged.
实体关系之@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;//订单创建日期
@Id
@GeneratedValue
public Integer getOrderid() {
return orderid;
}
public void setOrderid(Integer orderid) {
this.orderid = orderid;
}
@Column(name="amount")//name: 映射的列名,如果不指定映射列名,容器默认将属性名称作为的映射的数据库表列名。
public Float getAmount() {
return amount;
}
public void setAmount(Float amount) {
this.amount = amount;
}
/*
* @OneToMany: 指明Order 与OrderItem关联关系为一对多关系
*
* mappedBy: 定义类之间的双向关系。如果类之间是单向关系,不需要提供定义,如果类和类之间形成双向关系,我们就需要使用这个属性进行定义,
* 否则可能引起数据一致性的问题。
*
* cascade: CascadeType[]类型。该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作,
* 而且这种关系是递归调用的。举个例子:Order 和OrderItem有级联关系,那么删除Order 时将同时删除它所对应的OrderItem对象。
* 而如果OrderItem还和其他的对象之间有级联关系,那么这样的操作会一直递归执行下去。cascade的值只能从CascadeType.PERSIST(级联新建)、
* CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)中选择一个或多个。
* 还有一个选择是使用CascadeType.ALL,表示选择全部四项。
*
* fatch: 可选择项包括:FetchType.EAGER 和FetchType.LAZY。前者表示关系类(本例是OrderItem类)在主类(本例是Order类)加载的时候
* 同时加载;后者表示关系类在被访问时才加载,默认值是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 属性与数据库类型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",表示本实体对应数据库表 OrderItems,可选。
public class OrderItem implements Serializable {
private Integer id;//作为主键
private String productname;//产品名称
private Float price;//价格
private Order order;//对应的订单
/*
* 无参数构造器可别忘了
*/
public OrderItem() {
}
/*
* 带参数的构造器,用于初始化实例变量
*/
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之间为多对一关系,多个OrderItem实例关联的都是同一个Order对象。
* 其中的属性和@OneToMany基本一样,但@ManyToOne注释的fetch属性默认值是FetchType.EAGER。
*
* optional 属性是定义该关联类对是否必须存在,值为false时,关联类双方都必须存在,如果关系被维护端不存在,查询的结果为null。
* 值为true 时, 关系被维护端可以不存在,查询的结果仍然会返回关系维护端,在关系维护端中指向关系被维护端的属性为null。
* optional 属性的默认值是true。举个例:某项订单(Order)中没有订单项(OrderItem),如果optional 属性设置为false,
* 获取该项订单(Order)时,得到的结果为null,如果optional 属性设置为true,仍然可以获取该项订单,但订单中指向订单项的属性为null。
* 实际上在解释Order 与OrderItem的关系成SQL时,optional 属性指定了他们的联接关系optional=false联接关系为inner join,
* optional=true联接关系为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点实战经验你一定不知道!