欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hibernate cascade

程序员文章站 2024-02-20 11:12:40
...

1. 域模型与元数据

  • 域模型:创建实体的及其属性的概念模型叫域模型

  • 元数据选项:Hibernate持久化类及其属性与数据库表和列关联的方法

2. 映射持久化

  • 细粒度域模型:hibernate支持细粒度的富域模型,这是使用POJO的原因,简单来说,细粒度意味着类比表要多
  • 实体和值类型:@Entity和@Id注解映射一个持久化类,实体属性映射响应的值类型

3. 级联状态

如果可以跨越到另一个实体的关联来级联实体状态的状态变更,就只需要较少的代码来管理关系。细粒度控制有时对于表达关联实体之间的依赖性是必须的,JPA中用于此的机制是cascade的选项。

3.1 CascadeType.Persist

级联选项要用于想要传递的每个操作,因此要将CascadeType.PERSIST用于EntityManager#persist()操作。可以在简化item和bid保存它们的代码。

@Entity
public class Item {

    @Id
    @GeneratedValue(generator = Constants.ID_GENERATOR)
    protected Long id;

    protected String name;

    @OneToMany(mappedBy = "item", cascade = CascadeType.PERSIST)
    protected Set<Bid> bids = new HashSet<>();

    // ...
}

@Entity
public class Bid {

    @Id
    @GeneratedValue(generator = Constants.ID_GENERATOR)
    protected Long id;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    protected Item item;
}
//持久化
EntityManager em = JPA.createEntityManager();

Item someItem = new Item("Some Item");
em.persist(someItem); // Saves the bids automatically (later, at flush time)

Bid someBid = new Bid(new BigDecimal("123.00"), someItem);
someItem.getBids().add(someBid);

Bid secondBid = new Bid(new BigDecimal("456.00"), someItem);
someItem.getBids().add(secondBid);
tx.commit(); // Dirty checking, SQL execution
em.close();

在提交时,Hibernate会检查管理/持久化的Item实例并检查bids集合,之后会从内部在每个引用的Bid实例上调用persist()并且保存它们。

3.2 级联删除

在当前级联选项中,首先要移除Bid,在移除所有者Item,在@OneToMany注解上启用级联选项CascadeType.REMOVE后,持久化引擎可以自动移除关联的实体实例

 em = JPA.createEntityManager();

 Item item = em.find(Item.class, ITEM_ID);
 assertEquals(item.getBids().size(), 2);

 for (Bid bid : item.getBids()) {
    em.remove(bid);
 }
em.remove(item);



//启用CascadeType.REMOVE后
Item item = em.find(Item.class, ITEM_ID);
em.remove(item); 

删除需要加载该集合,因为每个Bid都是独立的实体实例,并且必须经历常规的生命周期。这一删除过程是低效的

3.3 级联合并(新增或修改)

CascadeType.MERGE:若Bid属性修改了,那么Item对象保存时同时修改items里的对象,对应EntityManager的merge方法 。

3.4 级联刷新

CascadeType.REFRESH:获取Item对象里也同时也重新获取最新的Bid的对象。对应EntityManager的refresh(object)方法有效。即会重新查询数据库里的最新数据。

4. 总结

新增和删除在项目中有部分使用场景,在删除时可以简化较多代码,但是数据关系复杂后带来的是数据量较大时的效率问题,关联关系会在数据库生成外键影响效率,有一个先从数据库获取数据,之后才能更新数据库数据,效率较低,要解决这里问题一个是深入研究Hibernate的内部机制提高效率,另一个是转向mybatis,提高灵活性。