在不考慮直接寫 query 的情況下,Hibernate entity 可以用 Hibernate ORM Hibernate Envers 底下的 code 來處理
抓取特定版本的eneity
Hibernate Envers 已經提供好 code 來抓取 entity 版本了
例如要抓取特定版本的eneity:
import org.hibernate.envers.*;
import org.hibernate.envers.query.*;
@Service
public class MyServiceImpl implements MyService{
@Autowired
private EntityManagerFactory entityManagerFactory;
public List<Number> getAllRevision(String id){
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction etx = em.getTransaction();
etx.begin();
AuditReader reader = AuditReaderFactory.get(em);
List<Number> revs = reader.getRevisions(MyEntity.class, id);
em.close();
return revs;
}
}
AuditReaderFactory.get();
可以是
org.hibernate.Session
或是
javax.persistence.EntityManager
,推薦使用
EntityManager。
這段 code 中,之所以不 @Autowired EntityManager
,而是
@Autowired EntityManagerFactory
,是因為自動注入的
EntityManager
,他的 connection 是關閉的。
所以才選擇用 factory 建立新的 EntityManager。
抓取Entity所有歷史版本
要抓取所有歷史版本可以這樣寫
AuditReader reader = AuditReaderFactory.get(em);
AuditQuery query = reader.createQuery()
.forRevisionsOfEntity(MyEntity.class, true, false)
.add(AuditEntity.id().eq(entityID));
List<?> result = query.getResultList();
forRevisionsOfEntity
的後面兩個參數分別是
- 是否只抓 entity
- 是否抓取「刪除」紀錄
如果第二個參數為 true
;則 result 會是
List<MyEntity>
類型。
如果不是,那他會是 List<Object[]>
。 Array 的
length 為 3
,分別是
- Entity
- org.hibernate.envers.DefaultRevisionEntity
- org.hibernate.envers.RevisionType
注意事項
- 上述範例我都沒有撰寫 try / catch ,實際上建議還是要寫。
- 不知為何,我用 java 1.8 compile 的時候,都會說 DefaultRevisionEntity 不存在(我用的 hibernate 版本是 5.4.25.Final )
參考資料
Envers - Hibernate ORM. Hibernate. https://hibernate.org/orm/envers/
良葛格, (N.d). 使用 EntityManager. Openhome. https://openhome.cc/Gossip/EJB3Gossip/EntityManager.html
Example usage for org.hibernate.envers AuditReaderFactory get. Java2s. http://www.java2s.com/example/java-api/org/hibernate/envers/auditreaderfactory/get-1-2.html
沒有留言:
張貼留言