hibernate 单向 双向有什么好的办法可以单向多对一,删除一可以级联删除多,或者外键置空吗?

没有更多推荐了,
不良信息举报
举报内容:
删除级联hibernate级联删除
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!Hibernate&一对多级联删除(转载)
大背景:,,,
Hibernate&一对多级联删除
系统中有表和表。分表表示帖子和帖子回复的表。一篇帖子可以有多个回复。
&&&&现在要求删除一篇帖子的同时删除对应的表中该帖子的所有回复。
&&&&&在中这样配置&(即在“一方”的hbm.xml文件中)
&set name="replaies" inverse="true" cascade="all" & 或者:cascade="delete"
&&&&&&操作删除的代码
Post post=postDAO.findById(postId);
postDAO.delete(post);
&&&&&&这样就会将某篇帖子及其回复全部删除了。
系统中有表和表。分表表示帖子和帖子回复的表。一篇帖子可以有多个回复。
打开某篇帖子,删除了其中的某一条“回复”。这时候要同时删除该主题贴以及所有回复。(不太符合常理)。
在post.hbm.xml中这样配置
&set name="replaies" inverse="true" cascade="all" &
或者:cascade="delete"
在replay.hbm.xml中这样配置
&many-to-one name="post"
class="com.lhp.hibernate.beans.Post"
fetch="select"
lazy="false"
cascade="delete" &
&column name="postId" not-null="true" /&
&/many-to-one&
操作删除的代码
Replay replay=replayDAO.findById(replayId);
replayDAO.delete(replay);
&&&&&&&&&&&&解读:在这个“一对多”关系中,“一方”和“多方”都设置了级联删除。那么删除了“多方”中的一条记录,就会级联删除“一方”中的记录,然后“一方”又会级联删除“多方”的所有记录。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。博客分类:
hibernate annotation一对多的级联删除,这个问题应该困扰了很多人吧,我也是被困扰了很久,为什么hibernate没有帮我们级联删除呢。
今天终于解决这个问题,下面给个例子大家,一定是可以级联删除的,之前在网上看了很多例子都无法做到,现在总结一下,给自己和给大家一点帮助。
annotation比xml的配置方便,却总感觉没有xml的功能强大。
用annotation的例子如下:
一个产品类型可以对多个产品,所以产品类型对产品的关系式一对多,产品类型的类如下:
import java.util.ArrayL
import java.util.L
import org.hibernate.annotations.C
//这里一定要用hibernate的annotation,不能用javax.persistence的
import org.hibernate.annotations.CascadeT
import javax.persistence.E
import javax.persistence.*;
import javax.persistence.T
import cn.com.dee.common.domain.DomainO
import cn.com.dee.dot.ProductTypeI
* 产品分类
* @author Dee
@Table(name = "RuixinPRODUCTTYPE")
public class ProductType implements DomainObject {
private static final long serialVersionUID = 2821257L;
private List&Product& products = new ArrayList&Product&();
//用于级联删除
public ProductType(){
public ProductType(ProductTypeInfo productTypeInfo) {
this.update(productTypeInfo);
public void update(ProductTypeInfo productTypeInfo){
this.code = productTypeInfo.getCode();
this.name = productTypeInfo.getName();
this.country = productTypeInfo.getCountry();
@Column(name = "ID", columnDefinition = "INT")
@GeneratedValue()
public String getId() {
@Column(name = "CODE", columnDefinition = "VARCHAR(40)")
public String getCode() {
@Column(name = "NAME", columnDefinition = "VARCHAR(50)")
public String getName() {
@Column(name = "COUNTRY", columnDefinition = "VARCHAR(50)")
public String getCountry() {
* 用于hibernate级联删除,删除了产品类型,把它下面的所有产品都一起删除
@OneToMany(targetEntity = Product.class,fetch = FetchType.LAZY)
@JoinColumn(name = "type")
@Cascade(value = {CascadeType.SAVE_UPDATE,
CascadeType.DELETE_ORPHAN,CascadeType.ALL})
public List&Product& getProducts() {
public void setCountry(String country) {
this.country =
public void setCode(String code) {
this.code =
public void setId(String id) {
public void setName(String name) {
this.name =
public void setProducts(List&Product& products) {
this.products =
产品的类如下:
import javax.persistence.C
import javax.persistence.E
import javax.persistence.GeneratedV
import javax.persistence.Id;
import javax.persistence.JoinC
import javax.persistence.ManyToO
import javax.persistence.T
import org.apache.commons.logging.L
import org.apache.commons.logging.LogF
import cn.com.dee.common.domain.DomainO
import cn.com.dee.dot.ProductI
* @author Ken
@Table(name = "RuixinPRODUCT")
public class Product implements DomainObject {
private static final long serialVersionUID = -0726153L;
private static final Log logger = LogFactory.getLog(Product.class);
* 产品全称
private String fullN
* 产品类型
private ProductT
//关联产品类型那边
// get方法
@Column(name = "ID", columnDefinition = "INT")
@GeneratedValue()
public String getId() {
//多对一对应product_type数据库里面的主码id
@ManyToOne
@JoinColumn(name = "TYPE", referencedColumnName = "ID", unique = false)
public ProductType getType() {
// set方法
public void setId(String id) {
public void setType(ProductType type) {
this.type =
调用hibernate底层的删除方法如下,只有调用这个方法才可以级联删除,自己写的sql语句是不能级联删除的:
public void delete(O object) {
//把产品类型的对象传进来
this.getHibernateTemplate().delete(object);
在service层的删除方法可以这样写:
* 删除产品类型,同时也删除该类型下面的产品
public void delete(ProductTypeInfo typeInfo) {
//把ProductTypeInfo转换为ProductType
ProductType type = new ProductType();
type.setId(typeInfo.getId());
type.setCode(typeInfo.getCode());
type.setCountry(typeInfo.getCountry());
type.setName(typeInfo.getName());
productTypeRepository.delete(type);
//调用hibernate底层的delete方法删除产品类型
到这里就大功告成!快去尝试一下吧,级联删除解决了,其他要怎么设计数据库,设计外键你都可以放心去做了,不会被这个搞到如此痛苦。
浏览 10213
请问下楼主。为什么不能用JPA的annotation而要用hibernate的??我查了一下jpa的api,貌似没有关于级联删除的参数,不知道这种解释对不对,不过用了hibernate的annotation就可以了
浏览: 11591 次
来自: 广州
太感谢了,解决困扰我一个星期的问题,特意登录上来标识感谢!
&div class=&quote_title ...
请问下楼主。为什么不能用JPA的annotation而要用hi ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'hibernate多对一、一对多(xml配置)public class Two { private I private S private Set&One& one = new HashSet&One&();
set/get方法省略
}public class One { private I private S private T
set/get方法省略
}多对一配置one.hbm.xml必须增加:约束:&!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
""&&hibernate-mapping package="(包名完成路径)hibernatetest"&&class name="one" table="one" &
&id name="id"&
&generator class="native"&&/generator&
&/id&&property name="name "&&/property&//name:引用的属性名;one实体类中属性Two的名称//column:外键名称//class:Two的路径(包的路径在package中已经声明,在此只需填类名)cascade:级联操作 save-update:级联保存操作更新delete:级联删除all:包含所有的级联操作(级联保存、更新、删除)&many-to-one name="two" column="tid" class="Two" cascade="all"&&/many-to-one&&/class&&/hibernate-mapping&一对多配置Two.hbm.xml必须增加:约束:&!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
""&&hibernate-mapping package="hibernatetest"& &class name="Two" table="two"&
&id name="id"&
&generator class="identity"&&/generator&
&property name="name"&&/property&//一对多name:集合属性名inverse:配置关系是否维护true:不维护false:维护(默认)注:必须有一方维护,一对多关系中,只能一的一方放弃维护
&set name="one" inverse="true" cascade="all"&//外键列名
&key column="tid"&&/key&//相关联的完整类名
&one-to-many class="One"&&/one-to-many&
&/set& &/class&&/hibernate-mapping&0添加评论分享收藏博客分类:
--数据库oracle
在数据库设计里,one-to-one模型可以用2种方法来实现。1,主键关联:这时候要保证2个表的主键具有完全相同的值。2,外键关联:其中一个表使用外键关联另一个表。
模型:person vs idcard (人:身份证)
--这是带主外键关联的两张表。-- 删除表DROP TABLEDROP TABLE
-- 创建表CREATE TABLE person( id VARCHAR2(32) PRIMARY KEY , name VARCHAR2(20) NOT NULL , age NUMBER) ;CREATE TABLE idcard( id VARCHAR2(32) REFERENCES person(id) ON DELETE CASCADE, serial VARCHAR2(18) NOT NULL , expiry NUMBER ) ;
2、pojo类public class Person { private S//perosn的id private S//名字
private IdC}
public class IdCard { private S//卡号 private S//卡的号码//可以使用年限 }
3、添加和删除的测试类。public class PersonIdCardOperation { private Session session =
public PersonIdCardOperation() {
this.session = new Configuration().configure().buildSessionFactory()
.openSession(); }
// 先插入一个用户 public void insert(Person per) {
this.session.save(per);
this.session.beginTransaction().commit();
session.close(); }
public void delete(String id) {
String hql = "DELETE FROM Person WHERE id=?" ;
Query q = this.session.createQuery(hql) ;
q.setString(0, id) ;
q.executeUpdate() ;
this.session.beginTransaction().commit() ; }
* @param args
*/ public static void main(String[] args) {
PersonIdCardOperation po = new PersonIdCardOperation();
Person per = new Person() ;
per.setName("jack");
per.setAge(25);
准备好一张身份证
IdCard ic = new IdCard();
ic.setSerial("888");
ic.setExpiry(12);
per.setIdcard(ic);
ic.setPerson(per);
po.insert(per) ;
po.delete("fff59cd080001"); }
4、person配置文件&hibernate-mapping& &class name="org.onetoone.com.Person" table="person"&
&id name="id" type="java.lang.String"&
&column name="id" length="32" /&
&generator class="uuid.hex"&&/generator&
&property name="name" type="java.lang.String"&
&column name="name" length="20" not-null="true" /&
&/property&
&property name="age" type="java.lang.Integer"&
&column name="age" /&
&/property&
&!-- 下面中的cascade="all",级联保存person对象关联的idcard对象。--&
&one-to-one name="idcard"
class="org.onetoone.com.IdCard"
cascade="all"
outer-join="true" &
&/one-to-one& &/class&&/hibernate-mapping&5、idCard配置文件&hibernate-mapping& &class name="org.onetoone.com.IdCard" table="idcard"& &!-- 引用Person的主键作为idCard的主键和外键 --&
&id name="id" column="id" type="java.lang.String"&
&generator class="foreign"&
&param name="property"&person&/param&
&/generator&
&one-to-one name="person"
class="org.onetoone.com.Person"
constrained="true"&
&/one-to-one&
&property name="serial" type="java.lang.String"&
&column name="serial" length="18" not-null="true" /&
&/property&
&property name="expiry" type="java.lang.Integer"&
&column name="expiry" not-null="true" /&
&/property& &/class&&/hibernate-mapping&
6、总结一些属性的用法。
person配置文件中的一些属性:
1、class="uuid.hex" 用uuid.hex会自动生成的一个32位值。
2、cascade="all" 解释一下cascade的用法:
all :所有情况下均进行关联操作,all 的意思是save-update + delete 。
none:所有情况下均不进行关联操作。这是默认值。
save-update:在执行save/update/saveOrUpdate时进行关联操作。
delete:在执行delete时进行关联操作。
all-delete-orphan 的意思是当对象图中产生孤儿节点时,在数据库中删除该节点
all比较好理解,举个例子说一下all-delete-orphan:
Category与Item是一对多的关系,也就是说Category类中有个Set类型的变量items.
举个例子,现items中存两个Item, item1,item2,如果定义关系为all-delete-orphan
当items中删除掉一个item(比如用remove()方法删除item1),那么被删除的Item类实例
将变成孤儿节点,当执行category.update(),或session.flush()时
hibernate同步缓存和数据库,会把数据库中item1对应的记录删掉
3、outer-join="true":解释一下outer-join的用法:
outer-join参数允许下列三个不同值:
auto:(默认) 使用外连接抓取关联(对象),如果被关联的对象没有代理(proxy)
true:一直使用外连接来抓取关联
false:永远不使用外连接来抓取关联
4、因为是双向关联,所以每个配置文件里面都要配&one-to-one&的关联关系
idCard配置文件中的一些属性:
constrained="true":解释一下constrained的用法。(这个属性的说明是个难点吧)
1、constrained的默认值是false。
2、级联删除我是在数据库层设置的。这里的constrained就没有什么用了。
3、要是不在数据库中控制级联删除。设个属性还是有用的。
hibernate中constrained主要是在one-to-one的foreign主键生成策略的映射中使用。手册上说:
constrained(约束) (可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对
主键进行约束。这个选项影响save()和delete()在级联执行时的先后顺序以及 决定该关联能否被委托(也在schema export tool
中被使用).
如果constrained=true,则表明存在外键与关联表对应,并且关联表中肯定存在对应的键与其对应。hibernate生成的sql将使用
inner join. 另外该选项最关键的是影响save和delete的先后顺序。例如增加的时候,如果constainted=true,则会先增加关联
表,然后增加本表。删除的时候反之
7、本程序的级联删除是在数据库层控制的。
jackroomage
浏览: 781477 次
来自: 北京
第一个方法是不对的
[color=orange][/color]包女包女不女
seagrave 写道这个算法想法不错,但太耗时,我用1、2、 ...
日常生活中,我们都不按你上面的那个方法算的!!!
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 hibernate 单向多对多 的文章

 

随机推荐