双向多对一/一对多例子
维护关系一方为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(); } } }