我正在学习Hibernate,只读了“Java Persistance with Hibernate”一书中的“7.2.3添加列连接表”一章。我的目标是在一个事务中保存Item,Category和CategorizedItem。
那里有一个构造函数(第305页):
public CategorizedItem(String username, Category category, Item item) {
// Set fields
this.username = username;
this.category = category;
this.item = item;
// Set identifier values
this.id.categoryId = category.getId();
this.id.itemId = item.getId();
// Guarantee referential integrity
category.getCategorizedItems().add(this);
item.getCategorizedItems().add(this);
}
它接受类别和项目对象。如果我创建一个Category和一个Item并希望用这种技术连接它们,那么它们显然必须保持BEFORE,因为category.getId()和item.getId()返回null。
是否有“Hibernate包中的技巧”可以级联保存连接表?连接表有其他列。我想在我的网页控制器中保存onSuccess处理程序中的所有三个对象。必须插入所有三个实体或不插入任何实体。
答案 0 :(得分:2)
你说
我的目标是在一次交易中保存Item,Category和CategorizedItem
Hibernate包中是否有可以级联保存连接表的技巧?
是的,使用MutableInt
@Entity
public class CategorizedItem implements Serializable {
private CategorizedItemId categorizedItemId;
private String userName;
private Category category;
private Item item;
/**
* required no-arg constructor
*/
public CategorizedItem() {}
public CategorizedItem(CategorizedItemId categorizedItemId) {
this.categorizedItemId = categorizedItemId;
}
public CategorizedItem(String userName, Category category, Item item) {
this.userName = userName;
this.categorizedItemId = new CategorizedItemId(category.getIdAsMutableInt(), item.getIdAsMutableInt());
}
@EmbeddedId
public CategorizedItemId getCategorizedItemId() {
return this.categorizedItemId;
}
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="CATEGORY_ID", insertable=false, updateable=false)
public Category getCategory() {
return this.category;
}
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ITEM_ID", insertable=false, updateable=false)
public Item getItem() {
return this.item;
}
// setter's goes here
/**
* It MUST implements Serializable
* It MUST overrides equals and hashCode method
* It MUST has a no-arg constructor
*
* Hibernate/JPA 1.0 does not support automatic generation of compound primary key
* You SHOULD set up manually
*/
@Embeddable
public static class CategorizedItemId implements Serializable {
private MutableInt categoryId = new MutableInt(-1);
private MutableInt itemId = new MutableInt(-1);
/**
* required no-arg constructor
*/
public CategorizedItemId() {}
public CategorizedItemId(MutableInt categoryId, MutableInt itemId) {
this.categoryId = categoryId;
this.itemId = itemId;
}
@Column(name="CATEGORY_ID", updateable=false, nullable=false)
public Integer getCategoryId() {
return this.categoryId.intValue();
}
public void setCategoryId(Integer categoryId) {
return this.categoryId.setValue(categoryId);
}
@Column(name="ITEM_ID", updateable=false, nullable=false)
public Integer getItemId() {
return this.itemId.intValue();
}
public void setItemId(Integer itemId) {
return this.itemId.setValue(itemId);
}
// getter's and setter's
@Override
public boolean equals(Object o) {
if(!(o instanceof CategorizedItemId))
return null;
finalCategorizedItemId other = (CategorizedItemId) o;
return new EqualsBuilder().append(getCategoryId(), other.getCategoryId())
.append(getItemId(), other.getItemId())
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(getCategoryId())
.append(getItemId())
.toHashCode();
}
}
}
这里是分类
@Entity
public class Category implements Serializable {
public MutableInt id = new MutableInt(-1);
private List<CategorizedItem> categorizedItemList = new ArrayList<CategorizedItem>();
@Transient
public MutableInt getIdAsMutableInt() {
return this.id;
}
@Id
@GeneratedValue
public Integer getId() {
return this.id.intValue();
}
public void setId(Integer id) {
return this.id.setValue(id);
}
@OneToMany(mappedBy="category")
@JoinColumn(name="CATEGORY_ID", insertable=false, updateable=false)
@Cascade(CascadeType.SAVE_UPDATE)
public List<CategorizedItem> getCategorizedItemList() {
return categorizedItemList;
}
// setter's
/**
* Use this method when you have a saved Item
*/
public void addCategorizedItem(CategorizedItem categorizedItem) {
categorizedItem.setCategorizedItemId(new CategorizedItemId(getIdAsMutableInt(), categorizedItem.getItem().getIdAsMutableInt()));
categorizedItem.setCategory(this);
getCategorizedItemList().add(categorizedItem);
}
}
和物品
@Entity
public class Item implements Serializable {
public MutableInt id = new MutableInt(-1);
private List<CategorizedItem> categorizedItemList = new ArrayList<CategorizedItem>();
@Transient
public MutableInt getIdAsMutableInt() {
return this.id;
}
@Id
@GeneratedValue
public Integer getId() {
return this.id.intValue();
}
public void setId(Integer id) {
return this.id.setValue(id);
}
@OneToMany(mappedBy="item")
@JoinColumn(name="ITEM_ID", insertable=false, updateable=false)
@Cascade(CascadeType.SAVE_UPDATE)
public List<CategorizedItem> getCategorizedItemList() {
return this.categorizedItemList;
}
// setter's
/**
* Use this method when you have a saved Category
*/
public void addCategorizedItem(CategorizedItem categorizedItem) {
categorizedItem.setCategorizedItemId(new CategorizedItemId(getIdAsMutableInt(), categorizedItem.getCategory().getIdAsMutableInt()));
categorizedItem.setItem(this);
getCategorizedItemList().add(categorizedItem);
}
}
现在因为在保存CategorizedItem之前需要categoryId和itemId ,请执行以下操作
Category category = new new Category();
Item item = new Item();
session.save(new Category());
session.save(new Item());
session.save(new CategorizedItem(userName, category, item));
请注意,当您拥有已保存的类别或已保存的项目时,级联才有效。否则,您需要按照上面显示的方法