Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.azrul.langkuik.dao; import com.fasterxml.uuid.EthernetAddress; import com.fasterxml.uuid.Generators; import com.fasterxml.uuid.impl.TimeBasedGenerator; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.Join; import javax.persistence.criteria.Order; import javax.persistence.criteria.Root; import org.hibernate.Session; import org.hibernate.metadata.ClassMetadata; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Set; import java.util.UUID; import javax.persistence.Query; import javax.persistence.metamodel.EntityType; import javax.persistence.metamodel.Metamodel; import javax.persistence.metamodel.SingularAttribute; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.azrul.langkuik.framework.relationship.RelationManager; import org.hibernate.CacheMode; import org.hibernate.search.annotations.Analyze; import org.hibernate.search.annotations.Index; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.jpa.FullTextEntityManager; import org.hibernate.search.jpa.FullTextQuery; import org.hibernate.search.jpa.Search; import org.hibernate.search.query.dsl.BooleanJunction; import org.hibernate.search.query.dsl.QueryBuilder; /** * * @author azrulm * @param <T> */ public class HibernateGenericDAO<T> implements DataAccessObject<T>, Serializable { private EntityManagerFactory emf; private Class<T> classOfEntity; // private static final ThreadLocal<EntityManager> threadLocal; // // static { // threadLocal = new ThreadLocal<EntityManager>(); // } public HibernateGenericDAO() { } public HibernateGenericDAO(EntityManagerFactory emf, Class<T> daoClass) { this.emf = emf; this.classOfEntity = daoClass; } @Override public Class<T> getType() { return classOfEntity; } public static void massIndexDatabaseForSearch(EntityManagerFactory emf) { try { EntityManager em = emf.createEntityManager(); List<Class> classes = new ArrayList<>(); for (EntityType e : emf.getMetamodel().getEntities()) { Class c = e.getJavaType(); if (c.isAnnotationPresent(Index.class)) { classes.add(c); } } FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search .getFullTextEntityManager(em); fullTextEntityManager.createIndexer(classes.toArray(new Class[] {})).batchSizeToLoadObjects(30) .optimizeAfterPurge(true).optimizeOnFinish(true).threadsToLoadObjects(4) .cacheMode(CacheMode.NORMAL) // defaults to CacheMode.IGNORE .startAndWait(); } catch (InterruptedException ex) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, ex); } } public T find(Object id) { T bean = null; EntityManager em = emf.createEntityManager(); bean = em.find(classOfEntity, id); em.close(); return bean; } //no persistence private T createNew(Class<T> clazz) { try { T bean = clazz.getConstructor().newInstance(new Object[] {}); return bean; } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, ex); } return null; } //no persistence public T createNew() { return createNew(classOfEntity); } //no persistence public T createNew(boolean giveId) { T bean = createNew(classOfEntity); if (giveId == true) { try { EthernetAddress addr = EthernetAddress.fromInterface(); TimeBasedGenerator uuidGenerator = Generators.timeBasedGenerator(addr); UUID uuid = uuidGenerator.generate(); Field field = bean.getClass().getDeclaredField(getIdentifierFieldName()); field.setAccessible(true); field.set(bean, new Long(uuid.clockSequence())); } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ex) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, ex); } } return bean; } private <P> Collection<T> getAllDependants(P parentObject, String parentField, String orderBy, boolean asc, int startIndex, int offset) { EntityManager em = emf.createEntityManager(); Order order = null; CriteriaBuilder cb = em.getCriteriaBuilder(); javax.persistence.criteria.CriteriaQuery<T> criteria = cb.createQuery(classOfEntity); Root parent = criteria.from(parentObject.getClass()); Join join = parent.join(parentField); Collection<T> results = new ArrayList<>(); //order by ClassMetadata classMetadata = ((Session) em.getDelegate()).getSessionFactory() .getClassMetadata(classOfEntity); if (orderBy == null && classMetadata != null) { orderBy = classMetadata.getIdentifierPropertyName(); } if (orderBy != null) { if (asc) { order = cb.asc(join.get(orderBy)); } else { order = cb.desc(join.get(orderBy)); } } if (orderBy == null) { //orderBy is still null criteria.select(join).where(cb.equal(parent, parentObject)); } else { criteria.select(join).where(cb.equal(parent, parentObject)).orderBy(order); } results = em.createQuery(criteria).setFirstResult(startIndex).setMaxResults(offset).getResultList(); em.close(); return results; } private <P> int countDependants(P parentObject, String parentField) { EntityManager em = emf.createEntityManager(); int count = -1; try { // em.getTransaction().begin(); // CriteriaBuilder builder = em.getCriteriaBuilder(); // javax.persistence.criteria.CriteriaQuery<T> criteria = builder.createQuery(daoClass); // Root parent = criteria.from(parentObject.getClass()); // criteria.select(parent.get(parentField)).where(parent.in(parentObject)); // T result = em.createQuery(criteria).setFirstResult(1).setMaxResults(1).getSingleResult(); // if (result != null) { if (!(parentObject.getClass().getDeclaredField(parentField) .getGenericType() instanceof ParameterizedType)) { return 1; } Class classOfField = (Class) ((ParameterizedType) parentObject.getClass().getDeclaredField(parentField) .getGenericType()).getActualTypeArguments()[0]; ClassMetadata classMetadata = ((Session) em.getDelegate()).getSessionFactory() .getClassMetadata(classOfField); String childId = classMetadata.getIdentifierPropertyName(); CriteriaBuilder countBuilder = em.getCriteriaBuilder(); javax.persistence.criteria.CriteriaQuery<Long> countCriteria = countBuilder.createQuery(Long.class); Root parentForCounting = countCriteria.from(parentObject.getClass()); countCriteria.select(countBuilder.count(parentForCounting.join(parentField).get(childId))) .where(parentForCounting.in(parentObject)); Long r = em.createQuery(countCriteria).getSingleResult(); if (r != null) { count = r.intValue(); } else { count = 0; } em.close(); } catch (Exception ex) { em.close(); Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, ex); } return count; } public <P> int count(P parentObject, String parentToCurrentField) { return countDependants(parentObject, parentToCurrentField); } public <P> Collection<T> find(P parentObject, String parentToCurrentField, String orderBy, boolean asc, int startIndex, int offset) { Collection<T> list = (Collection<T>) getAllDependants(parentObject, parentToCurrentField, orderBy, asc, startIndex, offset); return list; } @Override public void delete(T entity) { EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); boolean isIndexed = classOfEntity.isAnnotationPresent(Indexed.class); em.remove(refresh(em, entity)); if (isIndexed) { ftem.purge(classOfEntity, (Serializable) getIdentifierValue(entity)); } em.flush(); em.getTransaction().commit(); } catch (Exception e) { em.getTransaction().rollback(); Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); } em.close(); } @Override public void delete(Collection<T> entities) { EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); boolean isIndexed = classOfEntity.isAnnotationPresent(Indexed.class); for (T entity : entities) { em.remove(em.merge(entity)); if (isIndexed) { ftem.purge(classOfEntity, (Serializable) getIdentifierValue(entity)); } } em.flush(); em.getTransaction().commit(); } catch (Exception e) { em.getTransaction().rollback(); Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); } em.close(); } @Override public T save(T newObject) { EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); T savedObject = null; try { em.getTransaction().begin(); savedObject = em.merge(newObject); em.flush(); if (savedObject.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(savedObject); } em.getTransaction().commit(); return savedObject; } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return null; } @Override public <P> T createAndSave(DaoParameter<P, T> parameter) { if (parameter instanceof FindEntityCollectionParameter) { FindEntityCollectionParameter<P, T> feParam = (FindEntityCollectionParameter<P, T>) parameter; return createAndSave(feParam.getParentObject(), feParam.getParentToCurrentField(), feParam.getRelationManager()); } else { return createAndSave(); } } @Override public <P> T createAndSave(P parentBean, String parentToCurrentField, RelationManager<P, T> relationManager) { T newBean = createNew(); EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); ; T newBeanFromDB = em.merge(newBean); P parentBeanFromDB = refresh(em, parentBean); if (relationManager != null) { relationManager.link(parentBeanFromDB, newBeanFromDB, parentToCurrentField, em); } em.merge(parentBeanFromDB); em.merge(newBeanFromDB); em.flush(); // must flush before index if (newBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(newBeanFromDB); } if (parentBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { if (relationManager != null) { ftem.index(parentBeanFromDB); } } em.getTransaction().commit(); return newBeanFromDB; } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return null; } @Override public Object createAndSave(Class c) { EntityManager em = emf.createEntityManager(); try { Object bean = createNew(c);//call default constructor em.getTransaction().begin(); em.persist(bean); em.flush(); if (bean.getClass().isAnnotationPresent(Indexed.class)) { FullTextEntityManager ftem = Search.getFullTextEntityManager(em); ftem.index(bean); } em.getTransaction().commit(); return bean; } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return null; } @Override public T createAndSave() { T newObject = createNew(); EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); em.persist(newObject); em.flush(); if (newObject.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(newObject); } em.getTransaction().commit(); } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return newObject; } private Collection<T> getAll(Class<T> daoClass, String orderBy, boolean asc, int startIndex, int offset) { EntityManager em = emf.createEntityManager(); // ClassMetadata classMetadata = ((Session) em.getDelegate()).getSessionFactory().getClassMetadata(daoClass); // String childId = classMetadata.getIdentifierPropertyName(); String childId = this.getIdentifierFieldName(); CriteriaBuilder cb = em.getCriteriaBuilder(); javax.persistence.criteria.CriteriaQuery<T> criteria = cb.createQuery(daoClass); Root<T> root = criteria.from(daoClass); if (orderBy == null) { criteria.select(root).orderBy(cb.asc(root.get(childId))); } else { if (asc == true) { criteria.select(root).orderBy(cb.asc(root.get(orderBy))); } else { criteria.select(root).orderBy(cb.desc(root.get(orderBy))); } } Collection<T> results = em.createQuery(criteria).setFirstResult(startIndex).setMaxResults(offset) .getResultList(); em.close(); return results; } private int countAll(Class<T> daoClass) { EntityManager em = emf.createEntityManager(); ClassMetadata classMetadata = ((Session) em.getDelegate()).getSessionFactory().getClassMetadata(daoClass); String childId = classMetadata.getIdentifierPropertyName(); CriteriaBuilder cb = em.getCriteriaBuilder(); javax.persistence.criteria.CriteriaQuery<Long> criteria = cb.createQuery(Long.TYPE); Root<T> root = criteria.from(daoClass); criteria.select(cb.count(root.get(childId))); Long size = em.createQuery(criteria).getSingleResult(); em.close(); return size.intValue(); } @Override public int countSearch(Collection<SearchTerm> searchTerms, Class<T> daoClass) { if (searchTerms == null || searchTerms.isEmpty()) { return countAll(daoClass); } EntityManager em = emf.createEntityManager(); FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em); org.apache.lucene.search.Query luceneQuery = buildSearchQuery(fullTextEntityManager, daoClass, searchTerms); FullTextQuery ftQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, daoClass); return ftQuery.getResultSize(); } @Override public <P> Collection<T> runQuery(DaoParameter<P, T> query, String orderBy, boolean asc, int startIndex, int offset) { if (query instanceof FindAnyEntityParameter) { FindAnyEntityParameter searchQuery = (FindAnyEntityParameter) query; return search(searchQuery.getSearchTerms(), searchQuery.getSearchClass(), orderBy, asc, startIndex, offset); } else { FindEntityCollectionParameter entityQuery = (FindEntityCollectionParameter) query; return find(entityQuery.getParentObject(), entityQuery.getParentToCurrentField(), orderBy, asc, startIndex, offset); } } @Override public <P> int countQueryResult(DaoParameter<P, T> query) { if (query instanceof FindAnyEntityParameter) { FindAnyEntityParameter searchQuery = (FindAnyEntityParameter) query; return countSearch(searchQuery.getSearchTerms(), searchQuery.getSearchClass()); } else { FindEntityCollectionParameter entityQuery = (FindEntityCollectionParameter) query; return count(entityQuery.getParentObject(), entityQuery.getParentToCurrentField()); } } public Collection<T> search(Collection<SearchTerm> searchTerms, Class<T> daoClass, int startIndex, int offset) { return search(searchTerms, daoClass, null, true, startIndex, offset); } public Collection<T> search(Collection<SearchTerm> searchTerms, Class<T> daoClass, String orderBy, boolean asc, int startIndex, int offset) { if (searchTerms == null || searchTerms.isEmpty()) { return getAll(daoClass, orderBy, asc, startIndex, offset); } try { EntityManager em = emf.createEntityManager(); FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search .getFullTextEntityManager(em); //Session session = (Session) em.getDelegate(); //String currentIdField = session.getSessionFactory().getClassMetadata(daoClass).getIdentifierPropertyName(); String currentIdField = this.getIdentifierFieldName(); org.apache.lucene.search.Query luceneQuery = buildSearchQuery(fullTextEntityManager, daoClass, searchTerms); Sort sort = Sort.INDEXORDER; if (orderBy == null) { if (Long.TYPE.equals(daoClass.getDeclaredField(currentIdField).getType())) { sort = new Sort(new SortField(currentIdField, SortField.LONG, asc)); } else if (Integer.TYPE.equals(daoClass.getDeclaredField(currentIdField).getType())) { sort = new Sort(new SortField(currentIdField, SortField.INT, asc)); } else if (String.class.equals(daoClass.getDeclaredField(currentIdField).getType())) { sort = new Sort(new SortField(currentIdField, SortField.STRING, asc)); } } else { if (Long.TYPE.equals(daoClass.getDeclaredField(orderBy).getType())) { sort = new Sort(new SortField(orderBy, SortField.LONG, asc)); } else if (Integer.TYPE.equals(daoClass.getDeclaredField(orderBy).getType())) { sort = new Sort(new SortField(orderBy, SortField.INT, asc)); } else { //all else fail, sort as string sort = new Sort(new SortField(orderBy, SortField.STRING, asc)); } } Query jpaQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, daoClass).setSort(sort) .setFirstResult(startIndex).setMaxResults(offset); List<T> results = jpaQuery.getResultList(); fullTextEntityManager.close(); return results; } catch (NoSuchFieldException ex) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, ex); } return new ArrayList<T>(); } private org.apache.lucene.search.Query buildSearchQuery(FullTextEntityManager fullTextEntityManager, Class<T> daoClass, Collection<SearchTerm> searchTerms) { QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(daoClass).get(); BooleanJunction bj = qb.bool(); for (SearchTerm entry : searchTerms) { if (entry.getValue() instanceof Date) { bj.must(qb.range().onField(entry.getFieldName()).ignoreAnalyzer().below(entry.getValue()) .createQuery()); bj.must(qb.range().onField(entry.getFieldName()).ignoreAnalyzer().above(entry.getValue()) .createQuery()); } else { org.hibernate.search.annotations.Field searchFieldAnno = entry.getField() .getAnnotation(org.hibernate.search.annotations.Field.class); if (searchFieldAnno.analyze() == Analyze.NO) { bj.must(qb.keyword().onField(entry.getFieldName()).ignoreAnalyzer().matching(entry.getValue()) .createQuery()); } else { bj.must(qb.keyword().fuzzy().onField(entry.getFieldName()).matching(entry.getValue()) .createQuery()); } } } org.apache.lucene.search.Query luceneQuery = bj.createQuery(); return luceneQuery; } public <P> Collection<T> searchResultAlreadyInParent(Collection<T> searchResult, Class<T> daoClass, P parentObject, String parentToChildrenField) { try { EntityManager em = emf.createEntityManager(); Session session = (Session) em.getDelegate(); String currentIdField = session.getSessionFactory().getClassMetadata(daoClass) .getIdentifierPropertyName(); Collection searchResultIds = new ArrayList(); for (T a : searchResult) { Field idField = a.getClass().getDeclaredField(currentIdField); idField.setAccessible(true); searchResultIds.add(idField.get(a)); } CriteriaBuilder cb = em.getCriteriaBuilder(); javax.persistence.criteria.CriteriaQuery<T> criteria = cb.createQuery(daoClass); Root parent = criteria.from(parentObject.getClass()); Join join = parent.join(parentToChildrenField); criteria.select(join) .where(cb.and(cb.equal(parent, parentObject), join.get(currentIdField).in(searchResultIds))); List<T> filteredSearchResult = em.createQuery(criteria).getResultList(); session.close(); return filteredSearchResult; } catch (IllegalArgumentException ex) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, ex); } catch (SecurityException ex) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchFieldException ex) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, ex); } return new ArrayList<T>(); } @Override public <P> P associate(DaoParameter<P, T> parameter, Collection<T> newBeans) { if (parameter instanceof FindEntityCollectionParameter) { FindEntityCollectionParameter<P, T> feParam = (FindEntityCollectionParameter<P, T>) parameter; return associate(newBeans, feParam.getParentObject(), feParam.getParentToCurrentField(), feParam.getRelationManager()); } else { return null; } } @Override public <P> T saveAndAssociate(T newBean, P parentBean, String parentToNewBeanField, RelationManager<P, T> relationManager) { EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); T newBeanFromDB = em.merge(newBean); //P parentBeanFromDB = em.merge(parentBean); P parentBeanFromDB = refresh(em, parentBean); relationManager.link(parentBeanFromDB, newBeanFromDB, parentToNewBeanField, em); em.merge(newBeanFromDB); em.flush(); if (parentBeanFromDB != null && newBeanFromDB != null) { ftem.index(parentBeanFromDB); ftem.index(newBeanFromDB); } em.getTransaction().commit(); return newBeanFromDB; } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return null; } protected <P> P associate(Collection<T> newBeans, P parentBean, String parentToNewBeanField, RelationManager<P, T> relationManager) { EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); List<T> newBeansFromDB = new ArrayList<T>(); //P parentBeanFromDB = em.merge(parentBean); P parentBeanFromDB = refresh(em, parentBean); for (T newBean : newBeans) { T newBeanFromDB = refresh(em, newBean); relationManager.link(parentBeanFromDB, newBeanFromDB, parentToNewBeanField, em); em.merge(newBeanFromDB); newBeansFromDB.add(newBeanFromDB); } em.flush(); ftem.index(parentBeanFromDB); for (T newBean : newBeansFromDB) { ftem.index(newBean); } em.getTransaction().commit(); return parentBeanFromDB; } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return null; } private <E> E refresh(EntityManager em, E entity) { Object idValue = this.getIdentifierValue(entity); if (idValue == null) { return null; //cannot refresh something that does exist not in DB } E parentBeanFromDB = em.find((Class<E>) entity.getClass(), idValue); return parentBeanFromDB; } @Override public T refresh(T entity) { EntityManager em = emf.createEntityManager(); try { T entityFromDB = refresh(em, entity); return entityFromDB; } finally { em.close(); } } @Override public <P> P associate(DaoParameter<P, T> parameter, T newBean, T oldBean) { if (parameter instanceof FindEntityCollectionParameter) { FindEntityCollectionParameter<P, T> feParam = (FindEntityCollectionParameter<P, T>) parameter; return associate(newBean, oldBean, feParam.getParentObject(), feParam.getParentToCurrentField(), feParam.getRelationManager()); } else { return null; } } @Override public Object saveWithRelation(Object newBean, Object parentBean, String parentToNewBeanField, RelationManager relationManager) { EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); Object newBeanFromDB = em.merge(newBean); //Object newBeanFromDB = refresh(em, newBean); Object parentBeanFromDB = refresh(em, parentBean); relationManager.link(parentBeanFromDB, newBeanFromDB, parentToNewBeanField, em); em.merge(newBeanFromDB); em.merge(parentBeanFromDB); em.flush(); if (newBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(newBeanFromDB); } if (parentBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(parentBeanFromDB); } em.getTransaction().commit(); return parentBeanFromDB; } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return null; } protected <P> P associate(T newBean, T oldBean, P parentBean, String parentToBeanField, RelationManager<P, T> relationManager) { EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); T oldBeanFromDB = refresh(em, oldBean); T newBeanFromDB = refresh(em, newBean); P parentBeanFromDB = refresh(em, parentBean); if (oldBeanFromDB != null) { relationManager.unlink(parentBeanFromDB, oldBeanFromDB, parentToBeanField, em); } relationManager.link(parentBeanFromDB, newBeanFromDB, parentToBeanField, em); em.merge(newBeanFromDB); em.merge(parentBeanFromDB); if (oldBeanFromDB != null) { em.merge(oldBeanFromDB); } em.flush(); if (newBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(newBeanFromDB); } if (parentBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(parentBeanFromDB); } if (oldBeanFromDB != null) { if (oldBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(oldBeanFromDB); } } em.getTransaction().commit(); return parentBeanFromDB; } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return null; } @Override public <P> P unlink(DaoParameter<P, T> parameter, Collection<T> oldBeans) { if (parameter instanceof FindEntityCollectionParameter) { FindEntityCollectionParameter<P, T> feParam = (FindEntityCollectionParameter<P, T>) parameter; return unlink(oldBeans, feParam.getParentObject(), feParam.getParentToCurrentField(), feParam.getRelationManager()); } else { return null; } } // private <P> P unlinkAndDelete(T oldBean, P parentBean, RelationManager<P, T> relationManager) { // EntityManager em = emf.createEntityManager(); // FullTextEntityManager ftem = Search.getFullTextEntityManager(em); // // try { // em.getTransaction().begin(); // // P parentBeanFromDB = refresh(em, parentBean); // T oldBeanFromDB = refresh(em, oldBean); // relationManager.unlink(parentBeanFromDB, oldBeanFromDB, em); // em.remove(oldBeanFromDB); // // em.merge(parentBeanFromDB); // // em.flush(); // if (parentBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { // ftem.index(parentBeanFromDB); // } // // if (oldBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { // ftem.purge(classOfEntity, (Serializable) getIdentifierValue((T) oldBeanFromDB)); // } // // em.getTransaction().commit(); // // return parentBeanFromDB; // } catch (Exception e) { // Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); // em.getTransaction().rollback(); // } finally { // em.close(); // } // return null; // } @Override public Object unlinkAndDelete(Collection oldBeans, Object parentBean, String parentToNewBeanField, RelationManager relationManager) { EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); List oldBeansFromDB = new ArrayList(); Object parentBeanFromDB = refresh(em, parentBean); for (Object oldBean : oldBeans) { Object oldBeanFromDB = refresh(em, oldBean); relationManager.unlink(parentBeanFromDB, oldBeanFromDB, parentToNewBeanField, em); em.remove(oldBeanFromDB); oldBeansFromDB.add(oldBeanFromDB); } em.merge(parentBeanFromDB); em.flush(); if (parentBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(parentBeanFromDB); } for (Object oldBeanFromDB : oldBeansFromDB) { if (oldBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.purge(classOfEntity, (Serializable) getIdentifierValue((T) oldBeanFromDB)); } } em.getTransaction().commit(); return parentBeanFromDB; } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return null; } private <P> P unlink(Collection<T> oldBeans, P parentBean, String parentToCurrentField, RelationManager<P, T> relationManager) { EntityManager em = emf.createEntityManager(); FullTextEntityManager ftem = Search.getFullTextEntityManager(em); try { em.getTransaction().begin(); List<T> oldBeansFromDB = new ArrayList<T>(); P parentBeanFromDB = refresh(em, parentBean); for (T oldBean : oldBeans) { T oldBeanFromDB = refresh(em, oldBean); relationManager.unlink(parentBeanFromDB, oldBeanFromDB, parentToCurrentField, em); em.merge(oldBeanFromDB); oldBeansFromDB.add(oldBeanFromDB); } em.merge(parentBeanFromDB); em.flush(); if (parentBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(parentBeanFromDB); } for (T oldBeanFromDB : oldBeansFromDB) { if (oldBeanFromDB.getClass().isAnnotationPresent(Indexed.class)) { ftem.index(oldBeanFromDB); } } em.getTransaction().commit(); return parentBeanFromDB; } catch (Exception e) { Logger.getLogger(HibernateGenericDAO.class.getName()).log(Level.SEVERE, null, e); em.getTransaction().rollback(); } finally { em.close(); } return null; } public <C> Object getIdentifierValue(C entity) { Object id = emf.getPersistenceUnitUtil().getIdentifier(entity); return id; } @Override public String getIdentifierFieldName() { EntityManager em = emf.createEntityManager(); try { Metamodel metamodel = em.getMetamodel(); EntityType entity = metamodel.entity(classOfEntity); Set<SingularAttribute> singularAttributes = entity.getSingularAttributes(); for (SingularAttribute singularAttribute : singularAttributes) { if (singularAttribute.isId()) { return singularAttribute.getName(); } } } finally { em.close(); } return null; } }