- 双向一对多保存
一User对多Project,配置cascade时,如果cascade = CascadeType.PERSIST,则不能级联保存Project,cascade必须配置成All。 通过cascase配置控制反转。
@Entity
@Table(name = "t_user")
@Setter
@Getter
public
class User implements Serializable {
@Id
@GeneratedValue
private Long ID;
private String name;
private String age;
// 如果cascade不设置为ALL,则project不会被保存
@OneToMany(mappedBy = "user",cascade = CascadeType.PERSIST)
List<Project> projects;
}
@Entity
@Table(name = "t_project")
@Setter
@Getter
public
class Project implements Serializable {
@Id
@GeneratedValue
private Long ID;
private String name;
@ManyToOne
private User user;
}
public static void testSave(){
SessionFactory sf = HibernateUtils.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
List<Project> projects = new ArrayList<Project>();
Project p = new Project();
p.setName("proj12p");
projects.add(p);
User user = new User();
// 如果不给project设置User,则User和Project不能建立关系(project表中不会更新userid),只能各自保存各自。也就是说,一表是主表,多表是从表。控制侧一般会放在
p.setUser(user);
user.setName("testhiber1p");
user.setAge("4");
user.setProjects(projects);
session.save(user);
tx.commit();
session.close();
}
在Project配置cascade时,必须配置成ALL,不然使用save方法持久化到数据库时会报错,但使用persist方法不会。这是persist和save直接保存到库,返回ID的另一区别的又一区别。
任何双向关联关系只能有一个owning侧,另一个是inverse侧(也就是mappedby)。
2、Hibernate的更新有个缺点,就是更新之前必须要进行查询,也可能也就是面向对象转换关系数据库的一个缺点吧,生成SQL是全字段更新,因为他无法辨别你对象中的空值是真实的空值还是插入空值的要求。Mybatis更新只需要一个sql,其实hibernate也可以就是写SQL,这应该是hibernate自动生成对象的缺点。所以这也就是HQL,JPQL,Native SQL并存的根本原因。需要什么场景就用什么样的手段。不要纯粹主义者的偏执。