use of org.hibernate.metadata.ClassMetadata in project openmrs-core by openmrs.
the class HibernateOrderDAO method isOrderFrequencyInUse.
/**
* @see org.openmrs.api.db.OrderDAO#isOrderFrequencyInUse(org.openmrs.OrderFrequency)
*/
@Override
public boolean isOrderFrequencyInUse(OrderFrequency orderFrequency) {
Map<String, ClassMetadata> metadata = sessionFactory.getAllClassMetadata();
for (ClassMetadata classMetadata : metadata.values()) {
Class<?> entityClass = classMetadata.getMappedClass();
if (Order.class.equals(entityClass)) {
// ignore the org.openmrs.Order class itself
continue;
}
if (!Order.class.isAssignableFrom(entityClass)) {
// not a sub class of Order
continue;
}
String[] names = classMetadata.getPropertyNames();
for (String name : names) {
if (classMetadata.getPropertyType(name).getReturnedClass().equals(OrderFrequency.class)) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(entityClass);
criteria.add(Restrictions.eq(name, orderFrequency));
criteria.setMaxResults(1);
if (!criteria.list().isEmpty()) {
return true;
}
}
}
}
return false;
}
use of org.hibernate.metadata.ClassMetadata in project candlepin by candlepin.
the class AbstractHibernateCurator method lockAndLoadByIds.
/**
* Loads a collection of entities with a pessimistic lock using the specified entity class
* and collection of IDs. If no entities could be found matching the given IDs, this method
* returns an empty collection. Note that this method makes no attempt to ensure that an entity
* is loaded for every ID provided. It is possible for the output collection to be smaller than
* the provided set of IDs.
* <p></p>
* Depending on the session state when this method is called, this method may perform a refresh
* on each entity individually rather than performing a bulk lookup. This is due to a current
* limitation in Hibernate that forces use of the L1 cache when executing a query. To avoid
* this bottleneck, before calling this method, the caller should either evict the target
* entities from the session -- using session.evict or session.clear -- or use this method to
* perform the initial lookup straight away. Entities which are not already in the session
* cache will be fetched and locked in bulk, rather than refreshed and locked individually.
*
* @param entityClass
* The class representing the type of the entity to load (i.e. Pool.class or Product.class)
*
* @param ids
* A collection of IDs to use to load
*
* @return
* A collection of locked entities matching the given values
*/
protected Collection<E> lockAndLoadByIds(Class<E> entityClass, Iterable<? extends Serializable> ids) {
// The lockAndLoadById(s) methods work in two separate stages. The first stage determines
// whether or not an entity associated with a given ID is present in Hibernate's L1 cache.
// If it is, we need to fetch it from the cache and perform an explicit refresh operation
// for that entity. Otherwise, if it is not present, we can do a normal(ish) query to fetch
// it, and any other non-present entities.
//
// Unfortunately, there isn't a single, concise method for performing such a lookup.
// Instead, we need to check with the persistence context and determine whether or not it
// has an entity associated with a given entity key, which we generate using the session
// and entity persister. It's convoluted, but necessary to get consistently correct
// behavior from these methods.
List<E> result = new ArrayList<>();
if (ids != null && ids.iterator().hasNext()) {
EntityManager entityManager = this.getEntityManager();
SessionImpl session = (SessionImpl) this.currentSession();
ClassMetadata metadata = session.getFactory().getClassMetadata(entityClass);
if (metadata == null || !metadata.hasIdentifierProperty()) {
throw new UnsupportedOperationException("lockAndLoad only supports entities with database identifiers");
}
EntityPersister persister = session.getFactory().getEntityPersister(metadata.getEntityName());
PersistenceContext context = session.getPersistenceContext();
SortedSet<Serializable> idSet = new TreeSet<>();
SortedMap<Serializable, E> entitySet = new TreeMap<>();
// and which we need to lookup.
for (Serializable id : ids) {
// Make sure we don't doubly load/lock anything
if (id != null && !idSet.contains(id) && !entitySet.containsKey(id)) {
EntityKey key = session.generateEntityKey(id, persister);
E entity = (E) context.getEntity(key);
if (entity != null) {
entitySet.put(id, entity);
} else {
idSet.add(id);
}
}
}
// work.
if (entitySet.size() > 0) {
for (E entity : entitySet.values()) {
entityManager.refresh(entity, LockModeType.PESSIMISTIC_WRITE);
result.add(entity);
}
}
// Build a query to fetch the remaining entities
if (idSet.size() > 0) {
// Get the entity's metadata so we can ask Hibernate for the name of its identifier
String idName = metadata.getIdentifierPropertyName();
if (idName == null) {
// This shouldn't happen.
throw new RuntimeException("Unable to fetch identifier property name");
}
// Impl note:
// We're building the query here using JPA Criteria to avoid fiddling with string
// building and, potentially, erroneously using the class name as the entity name.
// Additionally, using a query (as opposed to the .find and .load methods) lets us set
// the flush, cache and lock modes for the entity we're attempting to fetch.
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<E> query = builder.createQuery(entityClass);
Root<E> root = query.from(entityClass);
Path<Serializable> target = root.<Serializable>get(idName);
ParameterExpression<List> param = builder.parameter(List.class);
query.select(root).where(target.in(param));
// Note that it's critical here to set both modes, as Hibernate is wildly inconsistent
// (and non-standard) in which properties it actually accepts when processing its own
// config objects. The cache mode combination specified below ends up being evaluated
// by Hibernate down to a CacheMode.REFRESH.
TypedQuery<E> executable = entityManager.createQuery(query).setFlushMode(FlushModeType.COMMIT).setHint(AvailableSettings.SHARED_CACHE_RETRIEVE_MODE, CacheRetrieveMode.BYPASS).setHint(AvailableSettings.SHARED_CACHE_STORE_MODE, CacheStoreMode.REFRESH).setLockMode(LockModeType.PESSIMISTIC_WRITE);
// Step through the query in blocks
for (List<Serializable> block : Iterables.partition(idSet, getBatchBlockSize())) {
executable.setParameter(param, block);
result.addAll(executable.getResultList());
}
}
}
// Should we be returning a view of the list, rather than the fully mutable list here?
return result;
}
use of org.hibernate.metadata.ClassMetadata in project BroadleafCommerce by BroadleafCommerce.
the class DynamicDaoHelperImpl method getIdField.
@Override
public Field getIdField(Class<?> clazz, EntityManager em) {
clazz = getNonProxyImplementationClassIfNecessary(clazz);
ClassMetadata metadata = em.unwrap(Session.class).getSessionFactory().getClassMetadata(clazz);
Field idField = ReflectionUtils.findField(clazz, metadata.getIdentifierPropertyName());
idField.setAccessible(true);
return idField;
}
use of org.hibernate.metadata.ClassMetadata in project BroadleafCommerce by BroadleafCommerce.
the class DynamicDaoHelperImpl method getAllPolymorphicEntitiesFromCeiling.
@Override
public Class<?>[] getAllPolymorphicEntitiesFromCeiling(Class<?> ceilingClass, SessionFactory sessionFactory, boolean includeUnqualifiedPolymorphicEntities, boolean useCache) {
ceilingClass = getNonProxyImplementationClassIfNecessary(ceilingClass);
Class<?>[] cache = null;
synchronized (LOCK_OBJECT) {
if (useCache) {
if (includeUnqualifiedPolymorphicEntities) {
cache = getCachedPolymorphicEntityList(POLYMORPHIC_ENTITY_CACHE, sessionFactory, ceilingClass);
} else {
cache = getCachedPolymorphicEntityList(POLYMORPHIC_ENTITY_CACHE_WO_EXCLUSIONS, sessionFactory, ceilingClass);
}
}
if (cache == null) {
List<Class<?>> entities = new ArrayList<>();
for (Object item : sessionFactory.getAllClassMetadata().values()) {
ClassMetadata metadata = (ClassMetadata) item;
Class<?> mappedClass = metadata.getMappedClass();
if (mappedClass != null && ceilingClass.isAssignableFrom(mappedClass)) {
entities.add(mappedClass);
}
}
Class<?>[] sortedEntities = sortEntities(ceilingClass, entities);
List<Class<?>> filteredSortedEntities = new ArrayList<>();
for (int i = 0; i < sortedEntities.length; i++) {
Class<?> item = sortedEntities[i];
if (includeUnqualifiedPolymorphicEntities) {
filteredSortedEntities.add(sortedEntities[i]);
} else {
if (isExcludeClassFromPolymorphism(item)) {
continue;
} else {
filteredSortedEntities.add(sortedEntities[i]);
}
}
}
Class<?>[] filteredEntities = new Class<?>[filteredSortedEntities.size()];
filteredEntities = filteredSortedEntities.toArray(filteredEntities);
cache = filteredEntities;
if (includeUnqualifiedPolymorphicEntities) {
Map<Class<?>, Class<?>[]> polymorphicEntityMap = buildPolymorphicEntityMap(POLYMORPHIC_ENTITY_CACHE.get(sessionFactory), ceilingClass, filteredEntities);
POLYMORPHIC_ENTITY_CACHE.put(sessionFactory, polymorphicEntityMap);
} else {
Map<Class<?>, Class<?>[]> polymorphicEntityMap = buildPolymorphicEntityMap(POLYMORPHIC_ENTITY_CACHE_WO_EXCLUSIONS.get(sessionFactory), ceilingClass, filteredEntities);
POLYMORPHIC_ENTITY_CACHE_WO_EXCLUSIONS.put(sessionFactory, polymorphicEntityMap);
}
}
}
return cache;
}
use of org.hibernate.metadata.ClassMetadata in project midpoint by Evolveum.
the class RUtil method fixCompositeIdentifierInMetaModel.
private static void fixCompositeIdentifierInMetaModel(SessionFactory sessionFactory, Class<?> clazz) {
ClassMetadata classMetadata = sessionFactory.getClassMetadata(clazz);
if (classMetadata instanceof AbstractEntityPersister) {
AbstractEntityPersister persister = (AbstractEntityPersister) classMetadata;
EntityMetamodel model = persister.getEntityMetamodel();
IdentifierProperty identifier = model.getIdentifierProperty();
try {
Field field = IdentifierProperty.class.getDeclaredField("hasIdentifierMapper");
field.setAccessible(true);
field.set(identifier, true);
field.setAccessible(false);
} catch (Exception ex) {
throw new SystemException("Attempt to fix entity meta model with hack failed, reason: " + ex.getMessage(), ex);
}
}
}
Aggregations