六盘水网站建设,一个网站一个月发多少外链比较合适,想注册个网站做短租房投资多少钱,深圳宝安区石岩街道Hibernate将开发人员的思维方式从思考SQL转变为思考对象状态转换。 根据Hibernate Docs#xff0c;实体可能处于以下状态之一#xff1a; new / transient#xff1a;实体不与持久性上下文关联#xff0c;因为它是数据库不知道的新创建的对象。 持久性#xff1a;实体与… Hibernate将开发人员的思维方式从思考SQL转变为思考对象状态转换。 根据Hibernate Docs实体可能处于以下状态之一 new / transient实体不与持久性上下文关联因为它是数据库不知道的新创建的对象。 持久性实体与持久性上下文相关联位于第一级缓存中并且存在一个表示该实体的数据库行。 分离实体以前与持久性上下文相关联但是持久性上下文已关闭或者手动撤消了该实体。 已删除实体被标记为已删除并且持久性上下文将在刷新时从数据库中将其删除。 通过调用EntityManager方法来将对象从一种状态移动到另一种状态例如 坚持 合并 去掉 级联允许将给定事件从父级传播到子级还简化了实体关系管理的管理。 在刷新期间Hibernate会将当前持久性上下文记录的更改转换为SQL查询。 现在考虑一下以下代码中发生了什么为简洁起见将其简化 Entity
public class Product {OneToMany(fetch FetchType.LAZY, cascade CascadeType.ALL, mappedBy product, orphanRemoval true)OrderBy(index)private Set images new LinkedHashSet();public Set getImages() {return images;}public void addImage(Image image) {images.add(image);image.setProduct(this);}public void removeImage(Image image) {images.remove(image);image.setProduct(null);}
}Entity
public class Image {Column(unique true)private int index;ManyToOneprivate Product product;public int getIndex() {return index;}public void setIndex(int index) {this.index index;}public Product getProduct() {return product;}public void setProduct(Product product) {this.product product;}
}final Long productId transactionTemplate.execute(new TransactionCallback() {Overridepublic Long doInTransaction(TransactionStatus transactionStatus) {Product product new Product();Image frontImage new Image();frontImage.setIndex(0);Image sideImage new Image();sideImage.setIndex(1);product.addImage(frontImage);product.addImage(sideImage);entityManager.persist(product);return product.getId();}
});try {transactionTemplate.execute(new TransactionCallback() {Overridepublic Void doInTransaction(TransactionStatus transactionStatus) {Product product entityManager.find(Product.class, productId);assertEquals(2, product.getImages().size());Iterator imageIterator product.getImages().iterator();Image frontImage imageIterator.next();assertEquals(0, frontImage.getIndex());Image sideImage imageIterator.next();assertEquals(1, sideImage.getIndex());Image backImage new Image();sideImage.setName(back image);sideImage.setIndex(1);product.removeImage(sideImage);product.addImage(backImage);entityManager.flush();return null;}
});fail(Expected ConstraintViolationException);
} catch (PersistenceException expected) {assertEquals(ConstraintViolationException.class, expected.getCause().getClass());
} 由于存在Image.index唯一约束因此在刷新期间会收到ConstraintviolationException。 您可能想知道为什么会发生这种情况因为在添加具有相同索引的backImage之前我们为sideImage调用remove并且答案是冲洗操作顺序。 根据Hibernate JavaDocs SQL操作顺序为 插入 更新 集合元素的删除 集合元素的插入 删除 因为我们的图像集合是“ mappedBy”所以图像将控制关联因此“ backImage”插入发生在“ sideImage”删除之前。 select product0_.id as id1_5_0_, product0_.name as name2_5_0_ from Product product0_ where product0_.id?
select images0_.product_id as product_4_5_1_, images0_.id as id1_1_1_, images0_.id as id1_1_0_, images0_.index as index2_1_0_, images0_.name as name3_1_0_, images0_.product_id as product_4_1_0_ from Image images0_ where images0_.product_id? order by images0_.index
insert into Image (id, index, name, product_id) values (default, ?, ?, ?)
ERROR: integrity constraint violation: unique constraint or index violation; UK_OQBG3YIU5I1E17SL0FEAWT8PE table: IMAGE 要解决此问题您必须在除去操作之后手动刷新持久性上下文 transactionTemplate.execute(new TransactionCallbackVoid() {Overridepublic Void doInTransaction(TransactionStatus transactionStatus) {Product product entityManager.find(Product.class, productId);assertEquals(2, product.getImages().size());IteratorImage imageIterator product.getImages().iterator();Image frontImage imageIterator.next();assertEquals(0, frontImage.getIndex());Image sideImage imageIterator.next();assertEquals(1, sideImage.getIndex());Image backImage new Image();backImage.setIndex(1);product.removeImage(sideImage);entityManager.flush();product.addImage(backImage);entityManager.flush();return null;}
}); 这将输出所需的行为 select versions0_.image_id as image_id3_1_1_, versions0_.id as id1_8_1_, versions0_.id as id1_8_0_, versions0_.image_id as image_id3_8_0_, versions0_.type as type2_8_0_ from Version versions0_ where versions0_.image_id? order by versions0_.type
delete from Image where id?
insert into Image (id, index, name, product_id) values (default, ?, ?, ?) 源代码在这里 。 参考 Hibernate Facts在Vlad Mihalcea的Blog博客上 我们的JCG合作伙伴 Vlad Mihalcea 知道冲洗操作的顺序很重要 。 翻译自: https://www.javacodegeeks.com/2013/11/hibernate-facts-knowing-flush-operations-order-matters.html