【hibernate学习杂记】维护关系的一方和不维护关系的一方的区别与联系

双向多对一/一对多例子

维护关系一方为User:多方

不维护关系的一方为Group:一方

以下是多方代码:

package Hibernate_demo1.Demo8.Entity.OneToManyAndManyToOne.BiDirectional;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

/**
 * @author pengys
 * @date 2017/8/4
 */

@Entity
@Table(name = "users")
public class User {

    // 双向一对多/多对一映射; 双向多对一/一对多映射; 是一样的

    @Id
    @Column(name = "id")
    @GenericGenerator(name = "gen", strategy = "uuid")
    @GeneratedValue(generator = "gen")
    private String id;

    @Column(name = "name")
    private String name;

    // 维护关系的一方:
    //      如果设置了group的值:
    //              1. 有CascadeType.ALL会发出group的sql, group和user都保存成功;
    //              2. 没有CascadeType.ALL, 由于本端维护关系, 所以会异常抛出(user对象引用了未保存的瞬时状态对象group), 除非你先手动持久化被维护关系的一方
    //      如果没有设置group的值:
    //              如果此关系是可选的option, 则允许保存但group为NULL
    //              如果此关系不是可选的, 则不允许保存, 抛出异常
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "group_id")
    private Group group;

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }
}

以下是一方代码:

package Hibernate_demo1.Demo8.Entity.OneToManyAndManyToOne.BiDirectional;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author pengys
 * @date 2017/8/4
 */

@Entity
@Table(name = "groups")
public class Group {

    // 双向一对多/多对一映射; 双向多对一/一对多映射; 是一样的

    @Id
    @Column(name = "id")
    @GenericGenerator(name = "gen", strategy = "uuid")
    @GeneratedValue(generator = "gen")
    private String id;

    @Column(name = "name")
    private String name;


    // 不维护关系的一方:
    //      如果设置了users的值: 根据是否有cascade属性来决定是否发起user的sql
    //              1. 有CascadeType.ALL会发出group的sql, group和user都保存成功;
    //              2. 没有CascadeType.ALL, 也不会异常抛出, 因为它不维护关系!!! 如果他要维护关系, 这必须取消mappedBy属性设置JoinColumn属性!!!
    //                 如果要维护关系, 取消了mappedBy属性却没有设置JoinColumn会导致第三张表(关系表)会被创建, 这不是双向多对一/一对多映射关系需要的
    //      如果没有设置users的值: 该映射关系没有可选选项, 因为该表不存在外键, 所以可选不可选其实没有意义, 可见ManyToOne关联关系只是在Java这一层, 底层还是多方存外键
    @OneToMany(mappedBy = "group", fetch = FetchType.EAGER)
//    @JoinColumn(name = "group_id") // mappedBy 和此 属性只能二选一: 双向应该由多方管理, 这样才不会发出多余sql, 选择 mappedBy
    private List<User> users = new ArrayList<>();

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
}

以下是测试代码:

package Hibernate_demo1.Demo8;

import Hibernate_demo1.Demo8.Entity.OneToManyAndManyToOne.BiDirectional.Group;
import Hibernate_demo1.Demo8.Entity.OneToManyAndManyToOne.BiDirectional.User;
import Hibernate_demo1.Demo8.Util.HibernateUtils;
import org.hibernate.Session;

/**
 * @author pengys
 * @date 2017/8/3
 */

public class TestOneToManyAndManyToOneBiDirectional {

    public static void main(String[] args) {

        Session session = null;
        try {

            session = HibernateUtils.getSession();
            session.beginTransaction();

            Group grp = new Group();
            grp.setName("group");

            User user = new User();
            user.setName("Test");

            User user2 = new User();
            user2.setName("C++");


//            user.setGroup(grp);
//            user2.setGroup(grp);
            grp.getUsers().add(user);
            grp.getUsers().add(user2);


            session.save(user);
            session.save(user2);
//            session.save(grp);

//            User user = session.get(User.class, "4028818f5db137a3015db137aaaf0000");
//            System.out.println(user.getName());
//            System.out.println("--------------------------------------------");
//            System.out.println(user.getGroup().getName());
//
//            Group grp = session.get(Group.class, "4028818f5db137a3015db137aab40001");
//            System.out.println(grp.getName());
//            System.out.println("--------------------------------------------");
//            System.out.println(grp.getUsers());


            session.getTransaction().commit();

        } catch (Exception e) {
            e.printStackTrace();
            if (session != null) {
                session.getTransaction().rollback();
            }
        } finally {
            HibernateUtils.closeSession(session);
            HibernateUtils.getSessionFactory().close();
        }

    }
}
原文地址:https://www.cnblogs.com/pengyusong/p/7290346.html