关于hibernate注解方法中一对多的级联更新

        最近做的项目中遇到很多各种表间关系是一对多对应的问题,开始自己弄的时候就去网上查,结果发现网上有关这方面的东西给的不是自己想要的,于是经过几天不停的更改测试终于算是勉强完成了级联更新的问题。在此把它记录下来以便日后复用

   先描述下问题。一个用户表tb_app_user,一个职业技能表tb_app_wl,一个特殊技能表tb_app_special,关系为用户表和职业技能表时一对一的关系,而一个职业技能表包含多个特殊技能即为一对多的关系。其实简单的只拿职业技能表和特殊技能表来说明问题就好。问题是在实际项目中职业技能表不可能单独存在,他必须需要关联自己的用户。因此还是把tb_app_user也拿出来了。如图为指导关系。

     用户在注册后会自动拥有这张tb_app_wl的表格,而tb_app_wl中也会包含三个tb_app_special,这种使用Hibernate中的级联操作很简单就可以实现。

持久类User:

@Entity(name = "TB_APP_USER")
@SelectBeforeUpdate(value = true)
@OptimisticLocking(type = OptimisticLockType.VERSION)
@Polymorphism(type = PolymorphismType.EXPLICIT)
@GenericGenerator(name = "systemUUID", strategy = "uuid")
public class User extends BaseObject {
    private static final long serialVersionUID = -3027223712328553788L;
    public static String user_name = "name";

    @Id
    @GeneratedValue(generator = "systemUUID")
    @Column(name = "ID")
    private String id;
    @OneToOne(mappedBy = "user", cascade = CascadeType.PERSIST)
    private WL wl;

    public WL getWl() {
        return wl;
    }

    public void setWl(WL wl) {
        this.wl = wl;
    }

    public String getSysId() {
        return id;
    }

    public void setSysId(String sysId) {
        this.id = sysId;
    }
}

cascade=CascadeType.PERSIST的意思是在执行persist()这个方法的时候会级联执行与他关联的数据插入操作。简单来说就是我注册一个用户User后,关联它的职业技能也会创建。下面列出WL持久类的实例

@Entity
@Table(name = "tb_app_wl", catalog = "hrborse")
@GenericGenerator(name = "wl", strategy = "uuid")
public class WL extends BaseObject {

    private static final long serialVersionUID = 1L;
    private String id;
    private User user;private Set<Special> speciallist = new HashSet<Special>();

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "wl")
    public Set<Special> getSpeciallist() {
        return speciallist;
    }

    public void setSpeciallist(Set<Special> speciallist) {
        this.speciallist = speciallist;
    }
    @Id
    @GeneratedValue(generator = "wl")
    @Column(name = "id")
    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id")
    public User getUser() {
        return this.user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

持久类 Special



@Entity
@Table(name = "tb_app_special", catalog = "hrborse")
@GenericGenerator(name = "special", strategy = "uuid")
public class Special extends BaseObject {

    private static final long serialVersionUID = 1L;
    private String id;
                private WL wl;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "wl_id")
    public WL getWl() {
        return wl;
    }

    public void setWl(WL wl) {
        this.wl = wl;
    }
     @Id
    @GeneratedValue(generator = "special")
    @Column(name = "id")
    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

}

 

然后把执行级联操作代码贴出来

public String register() {
          User user = new User();
           user.setName(name);
           user.setEmail(email);
           user.setModifiedBy("SYS");
           WL wl = new WL();
        Set<Special> specialList = new HashSet<Special>();
           Special special1 = new Special();
           Special special2 = new Special();
           Special special3 = new Special();
           special1.setWl(wl);
           special2.setWl(wl);
           special3.setWl(wl);
           specialList.add(special1);
           specialList.add(special2);
           specialList.add(special3);
           wl.setUser(user);
           wl.setSpeciallist(specialList);
           user.setWl(wl);
           userService.registerUser(user);
           return SUCCESS;
    }

 

注意set方法的对应,这样子在注册一个用户后就数据库里也会拥有wl和special的数据,他们都拥有主键以及关联的外键,但是其他数据都是null,接下来就是更新着写null的数据,拿我们的新数据update,对于wl,我们登录后可以由:user.getWl().getId获得,但是无法获得special因为它是多个属性不可能从这里获取,所以需要按照special关联的外键wl_id查出所有的special,然后遍历放入相应的wl属性中,最后只对wl进行更新便可完成对其对应special的更新,这样的好处就是用户单击保存信息后不会无限创建新表了。

public String saveWL() {
        User user = (User) session.get("user");
        int count=0;
        Set<Special> listspecial = new      HashSet<Special>();
        wl.setId(user.getWl().getId());
        wl.setUser(user);
        wl.setWSw(wsw);
        wl.setSkillCertificate(skillcertificate);
        wl.setCertificate(certificate);
        wl.setLanguage(language);
        wl.setLiteracy(literacy);
        wl.setListenSkill(listenskill);
        String id = wl.getId();
        List<Special> lis = wlService.findSpecialListById(id);
        for (Special specials : lis) {
            if(count==0){
                special.setId(specials.getId());
                special.setWl(wl);
                listspecial.add(special);
            }
            if(count==1){
                special2.setId(specials.getId());
                special2.setWl(wl);
                listspecial.add(special2);
            }
            if(count==2){
                special3.setId(specials.getId());
                special3.setWl(wl);
                listspecial.add(special3);
            }
            count++;
            
        }
        wl.setSpeciallist(listspecial);
        user.setWl(wl);
        wlService.updateWL(user.getWl());
        return SUCCESS;

    }

 

posted @ 2013-01-11 20:19  塔塔兔  阅读(2202)  评论(0编辑  收藏  举报