📄 hibernatehistorytest.java
字号:
package net.jeffrey.hibernate.history;import java.util.List;import javax.persistence.EntityManager;import javax.persistence.Persistence;import net.jeffrey.hibernate.Category;import net.jeffrey.hibernate.Product;import org.junit.After;import org.junit.Before;import org.junit.Test;import static org.junit.Assert.*;import static net.jeffrey.hibernate.history.OperationType.*;/** * Hibernate 审计日志测试用例 * @author jeffrey */public class HibernateHistoryTest { private EntityManager em; public HibernateHistoryTest() { } @Before public void setUp() { em = Persistence.createEntityManagerFactory("HibernateAuditHistoryPU").createEntityManager(); } @After public void tearDown() { em.close(); } @Test // 测试审计日志:创建对象 public void testCreateHistory() { Product p = new Product(); p.setName("Hibernate in Action"); // 保存新商品 em.getTransaction().begin(); em.persist(p); em.getTransaction().commit(); // 查找该对象关联的操作日志 List<HistoryEntry> list = em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Product.class) .setParameter("entityId", p.getId()).getResultList(); assertEquals(1, list.size()); HistoryEntry h = list.get(0); // 日志关联的实体类型与商品类应该相同 assertEquals(Product.class.getName(), h.getEntity().getName()); // 测试日志关联的实体id是否正确 assertEquals(p.getId(), h.getEntityId()); // 该日志的操作类型应该是CREATE类型 assertEquals(CREATE, h.getOperationType()); // 测试是否正确生成了日期戳 assertNotNull(h.getTimestamp()); } @Test // 测试审计日志:简单属性的更新 public void testUpdatePropertyHistory() { Product p = em.find(Product.class, 1); assertNotNull(p); assertEquals("Core Java", p.getName()); p.setName("Core Java I"); em.getTransaction().begin(); em.merge(p); em.getTransaction().commit(); HistoryEntry h = (HistoryEntry) em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Product.class) .setParameter("entityId", p.getId()).getSingleResult(); assertEquals(Product.class.getName(), h.getEntity().getName()); assertEquals(p.getId(), h.getEntityId()); assertEquals(UPDATE, h.getOperationType()); // 更新的属性是name assertEquals("name", h.getProperty()); // 更新前的值 assertEquals("Core Java", h.getPreviousValue()); // 更新后的值 assertEquals("Core Java I", h.getNewValue()); assertNotNull(h.getTimestamp()); } @Test // 测试审计日志:更新值与旧值相同 public void testUpdatePropertyBySameValue() { Product p = em.find(Product.class, 2); assertNotNull(p); assertEquals("JSF in Action", p.getName()); em.getTransaction().begin(); // 更新的值与原有值一样 p.setName("JSF in Action"); em.merge(p); em.getTransaction().commit(); List list = em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Product.class) .setParameter("entityId", p.getId()).getResultList(); // 并没有实际更新值,不应该生成审计日志 assertTrue(list.isEmpty()); } @Test // 测试审计日志:多对一的关联对象的更新 public void testUpdateManyToOneMappingHistory() { Product p = em.find(Product.class, 3); assertEquals("iPhone", p.getName()); Category c1 = p.getCategory(); assertEquals("Mobile phone", c1.getName()); Category c2 = em.find(Category.class, 5); assertEquals("Toy", c2.getName()); em.getTransaction().begin(); // 变更该商品的类别,商品和类别是many to one p.setCategory(c2); em.merge(p); em.getTransaction().commit(); HistoryEntry h = (HistoryEntry)em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Product.class) .setParameter("entityId", p.getId()).getSingleResult(); assertEquals(Product.class.getName(), h.getEntity().getName()); assertEquals(UPDATE, h.getOperationType()); // 更新的属性是category assertEquals("category", h.getProperty()); // 原有值应该是该商品原有类别的id assertEquals(c1.getId().toString(), h.getPreviousValue()); // 新值应该是新类别的id assertEquals(c2.getId().toString(), h.getNewValue()); } @Test // 测试审计日志:一对多的关联对象的更新 public void testUpdateOneToManyMappingHistory() { Category c = em.find(Category.class, 6); assertEquals("Car", c.getName()); assertEquals(2, c.getProducts().size()); Product p = c.getProducts().get(1); assertEquals("SU-27", p.getName()); em.getTransaction().begin(); // 从一个类别Car中去除一个商品SU-27,类别和商品是 one to many c.removeProduct(p); em.merge(c); em.getTransaction().commit(); List list = em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Category.class) .setParameter("entityId", c.getId()).getResultList(); // 在category和product的一对多关联中,product是主控端,hibernate只会触发与product关联的更新事件 // 所以category没有关联该次更新操作的审计日志 assertTrue(list.isEmpty()); HistoryEntry h = (HistoryEntry) em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Product.class) .setParameter("entityId", p.getId()).getSingleResult(); assertNotNull(h); // 但是,类别Car删除商品SU-27,商品SU-27与类别Car解除了关联关系。则会生成相应的更新审计日志 assertEquals(Product.class.getName(), h.getEntity().getName()); assertEquals(p.getId(), h.getEntityId()); assertEquals("category", h.getProperty()); assertEquals(UPDATE, h.getOperationType()); assertEquals(c.getId().toString(), h.getPreviousValue()); assertNull(h.getNewValue()); } @Test // 测试审计日志:删除对象 public void testDeleteHistory() { Product p = em.find(Product.class, 2); assertNotNull(p); assertEquals("JSF in Action", p.getName()); em.getTransaction().begin(); em.remove(p); em.getTransaction().commit(); assertNull(em.find(Product.class, 2)); HistoryEntry h = (HistoryEntry) em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Product.class) .setParameter("entityId", p.getId()).getSingleResult(); // 实体对象已经删除,但是通过其id仍然可以访问到操作历史的记录 assertEquals(Product.class.getName(), h.getEntity().getName()); assertEquals(DELETE, h.getOperationType()); assertNotNull(h.getTimestamp()); } @Test // 测试审计日志:级联删除对象 public void testCascadeDeleteHistory() { Category c = em.find(Category.class, 2); assertEquals("Movie", c.getName()); em.getTransaction().begin(); em.remove(c); em.getTransaction().commit(); // category 和 product是级联一对多的关系,如果删除了category,会生成相应的所有关联对象的删除操作日志 HistoryEntry h1 = (HistoryEntry) em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Product.class) .setParameter("entityId", 6).getSingleResult(); assertNotNull(h1); assertEquals(DELETE, h1.getOperationType()); HistoryEntry h2 = (HistoryEntry) em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Product.class) .setParameter("entityId", 7).getSingleResult(); assertNotNull(h2); assertEquals(DELETE, h2.getOperationType()); HistoryEntry h3 = (HistoryEntry) em.createNamedQuery("HistoryEntry.findByEntity") .setParameter("entity", Category.class) .setParameter("entityId", 2).getSingleResult(); assertEquals(DELETE, h3.getOperationType()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -