• Hibernate级联操作 注解



    EJB3 支持的操作类型

    /**
     * Cascade types (can override default EJB3 cascades
     */
    public enum CascadeType {
    	ALL,
    	PERSIST,
    	MERGE,
    	REMOVE,
    	REFRESH,
    	DELETE,
    	SAVE_UPDATE,
    	REPLICATE,
    	/** @deprecated use @OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true) */
    	@Deprecated
    	DELETE_ORPHAN,
    	LOCK,
    	/** @deprecated use javax.persistence.CascadeType.DETACH */
    	@Deprecated
    	EVICT,
    	DETACH
    }
    

    级联更新保存

     @JoinColumn(name = "conf_file_id", referencedColumnName = "conf_file_id",insertable = true,updatable = true)
        @Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})


    级联删除

      @OneToMany(mappedBy = "projectByProPlanId",orphanRemoval=true)
        @Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})

    save-update: 级联保存(load以后如果子对象发生了更新,也会级联更新). 但它不会级联删除
    delete: 级联删除, 但不具备级联保存和更新
    all-delete-orphan: 在解除父子关系时,自动删除不属于父对象的子对象, 也支持级联删除和级联保存更新.
    all: 级联删除, 级联更新,但解除父子关系时不会自动删除子对象. 

    delete-orphan:删除所有和当前对象解除关联关系的对象 

     

    注意:以上设在哪一段就是指对哪一端的操作而言,比如delete,如果设在one的一端的<set>属性里,就是当one被删除的时候,自动删除所有的子记录;

    如果设在many一端的<many-to-one>标签里,就是在删除many一端的数据时,会试图删除one一端的数据,如果仍然有many外键引用one,就会报“存在子记录”的错误;如果在one的一端同时也设置了cascade=“delete”属性,就会发生很危险的情况:删除many一端的一条记录,会试图级联删除对应的one端记录,因为one也设置了级联删除many,所以其他所有与one关联的many都会被删掉。

    所以,千万谨慎在many一端设置cascade=“delete”属性。

    故此cascade一般用在<one-to-one>和<one-to-many>中


    以下转载自:http://blog.csdn.net/sinlff/article/details/7342527

    很多人对持久层概念搞不清JPA、Hibernate、EJB3.0的关系,这里做一下简单的说明:JPA是一个持久层设计接口,EJB3.0和Hibernate是具体的实现类,EJB3.0和Hibernate的功能近似相等的(Hibernate没有Session Bean,Spring MVC3的SessionAttribute跟Session Bean近似)。

    理论是使用JPA接口可以无缝切换持久层实现,但是仅仅是理论上!!!


    JPA是在Hibernate成熟并大行其道的时候才推出的,基本上是借鉴Hibernate的优点,做了一个统一的标准而已,JPA1.0没有一对多的级联删除配置,也许JPA2.0里才有吧(这里没做过调研)
    @OneToMany(mappedBy = "commentTeam")
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    private Set<CommentTeamMember> commentTeamMembers;
    这里为了说明,只贴出一对多的关键代码,其它无关的注解已忽略掉,以免造成干扰。
    这里重点说明一下四个常用的注解配置的区别:
    CascadeType.SAVE_UPDATE
    CascadeType.ALL
    CascadeType.DELETE
    CascadeType.DELETE_ORPHAN


     之所有之列出这四个,是因为我不想跟书本上把所有的概念都罗列出来。基本上开发时其中的3个都以及足够用了,下面我结合代码演示一下他们之间的区别,以及使用的时候注意的地方。
    CascadeType.SAVE_UPDATE:Hibernate专有的,JPA并不支持,作用是级联保存、级联更新(注:JPA很恶心,要么你配置
    CascadeType.ALL,要么你配CascadeType.SAVE+CasadeType.Merge。八卦一句:专家虽牛,多年不写代码,定的标准让编码麻烦呀!)
    CascadeType.ALL:级联保存、修改、删除、同步,一般很少用,看看控制台的一长串SQL就知道性能低下,你没改的关联表也给你发update语句,我从来没用过这个属性。
    CascadeType.DELETE:当调用session.delete(A)的时候,级联删除关联的对象。(注:先调用A.setB(null),再调用session.delete(A),这样是级联删不掉B的。
    CascadeType.DELETE_ORPHAN:一对多级联删除。


    下面重点来说说这个CascadeType.DELETE_ORPHAN:
    看过API、开发指南,级联删除就一个经典的
    @OneToMany(mappedBy = "commentTeam")
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.DELETE_ORPHAN})
    private Set<CommentTeamMember> commentTeamMembers;


    mappedBy不可少,映射A->B一对多的另一边控制反转(谁控谁的问题),新版的Hibernate3.4中配置更简单,变一句了,更简洁吧?
    @OneToMany(mappedBy = "commentTeam",orphanRemoval=true) 

    private Set<CommentTeamMember> commentTeamMembers;


    CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
    commentTeam.setCommentTeamMember(null);//想级联删除子表数据
    this.getHibernateTemplate.saveOrUpdate(commentTeam);
    这样级联删除却没有发生,为什么呢?
    再来一个例子
    CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
    Set<CommentTeamMember> commentTeamMembers=new HashSet<CommentTeamMember>();
    commentTeam.setCommentTeamMember(commentTeamMembers);//想级联删除子表数据或增减替换对象
    this.getHibernateTemplate.saveOrUpdate(commentTeam);
    这个例子级联删除的效果也没发生!即使commentTeamMembers里有若干个对象。


    成功执行级联删除的语法:
    CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
    commentTeam.getCommentTeamMember().clear();//注意这里引用的集合还是原来的集合,这里没有重新new过
    commentTeam.getCommentTeamMember().add(new CommentTeamMember());//如果想替换为新的集合可以用addAll方法
    this.getHibernateTemplate.saveOrUpdate(commentTeam);

    分析一下原因:级联删除起作用的前提是关联的集合对象不能重新指向新的引用,必须在原有的集合里操作新增、删除、清空元素,像上面的setXXX(null)的方法等是起不到级联删除作用的,大概是Hibernate自认自己原生的集合对象吧,自己New的放进行级联删除无效!


  • 相关阅读:
    spark发现新词
    树的算法总结
    机器学习树的算法总结
    Spark Streaming实例
    ubuntu上通用解压方式
    论MYSQL数据库数据错误的处理
    macOS Sierra上Opencv的安装与使用
    phpstudy2016 redis扩展 windows
    细说PHP7
    正则表达式与.htaccess的配置
  • 原文地址:https://www.cnblogs.com/pangblog/p/3369542.html
Copyright © 2020-2023  润新知