private void buildEntityInfo() { BeanUtils.reflections.getTypesAnnotatedWith(Entity.class).forEach(clz-> { entityInfoMap.put(clz, new EntityInfo(clz)); }); }
private void hardDelete(Collection ids) { String tblName = hasEO() ? eoClass.getSimpleName() : voClass.getSimpleName(); String sql = String.format("delete from %s eo where eo.%s in (:ids)", tblName, voPrimaryKeyField.getName()); Query q = getEntityManager().createQuery(sql); q.setParameter("ids", ids); q.executeUpdate(); logger.debug(String.format("hard delete %s records from %s", ids.size(), tblName)); fireHardDeleteExtension(ids); }
void entityEvent(EntityEvent evt, Object entity) { EntityInfo info = entityInfoMap.get(entity.getClass()); if (info == null) { logger.warn(String.format("cannot find EntityInfo for the class[%s], not entity events will be fired", entity.getClass())); return; } info.fireLifeCycleEvent(evt, entity); } }
private void updateEO(Object entity, DataIntegrityViolationException de) { if (!MySQLIntegrityConstraintViolationException.class.isAssignableFrom(de.getRootCause().getClass())) { throw de; } MySQLIntegrityConstraintViolationException me = (MySQLIntegrityConstraintViolationException) de.getRootCause(); if (!(me.getErrorCode() == 1062 && "23000".equals(me.getSQLState()) && me.getMessage().contains("PRIMARY"))) { throw de; } if (!hasEO()) { throw de; } // at this point, the error is caused by a update tried on VO entity which has been soft deleted. This is mostly // caused by a deletion cascade(e.g deleting host will cause vm running on it to be deleted, and deleting vm is trying to return capacity // to host which has been soft deleted, because vm deletion is executed in async manner). In this case, we make the update to EO table Object idval = getEOPrimaryKeyValue(entity); Object eo = getEntityManager().find(eoClass, idval); final Object deo = ObjectUtils.copy(eo, entity); new Runnable() { @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void run() { getEntityManager().merge(deo); } }.run(); logger.debug(String.format("A EO[%s] update has been made", eoClass.getName())); }
EntityInfo(Class voClazz) { voClass = voClazz; voPrimaryKeyField = FieldUtils.getAnnotatedField(Id.class, voClass); DebugUtils.Assert(voPrimaryKeyField != null, String.format("%s has no primary key", voClass)); voPrimaryKeyField.setAccessible(true); EO at = (EO) voClazz.getAnnotation(EO.class); if (at != null) { eoClass = at.EOClazz(); DebugUtils.Assert(eoClass != null, String.format("cannot find EO entity specified by VO entity[%s]", voClazz.getName())); eoPrimaryKeyField = FieldUtils.getAnnotatedField(Id.class, eoClass); DebugUtils.Assert(eoPrimaryKeyField != null, String.format("cannot find primary key field(@Id annotated) in EO entity[%s]", eoClass.getName())); eoPrimaryKeyField.setAccessible(true); eoSoftDeleteColumn = FieldUtils.getField(at.softDeletedColumn(), eoClass); DebugUtils.Assert(eoSoftDeleteColumn != null, String.format("cannot find soft delete column[%s] in EO entity[%s]", at.softDeletedColumn(), eoClass.getName())); eoSoftDeleteColumn.setAccessible(true); } buildInheritanceDeletionExtension(); buildSoftDeletionCascade(); }
private void softDelete(Object entity) { try { Object idval = getEOPrimaryKeyValue(entity); if (idval == null) { // the entity is physically deleted return; } Object eo = getEntityManager().find(eoClass, idval); eoSoftDeleteColumn.set(eo, new Timestamp(new Date().getTime()).toString()); getEntityManager().merge(eo); fireSoftDeleteExtension(Arrays.asList(idval), voClass); fireSoftDeleteExtensionByEOClass(Arrays.asList(idval), eoClass); } catch (CloudRuntimeException ce) { throw ce; } catch (Exception e) { throw new CloudRuntimeException(e); } }
@Transactional(propagation = Propagation.REQUIRES_NEW) Object reload(Object entity) { return getEntityManager().find(entity.getClass(), getVOPrimaryKeyValue(entity)); }
@Transactional(propagation = Propagation.REQUIRES_NEW) void removeCollection(Collection entities) { for (Object entity : entities) { if (!entity.getClass().isAnnotationPresent(EO.class)) { hardDelete(entity); } else { softDelete(entity); } } }
@Transactional(propagation = Propagation.REQUIRES_NEW) void removeByPrimaryKeys(Collection ids) { if (hasEO()) { softDelete(ids); } else { hardDelete(ids); } }
private void softDelete(Collection ids) { String sql = String.format("update %s eo set eo.%s = (:date) where eo.%s in (:ids)", eoClass.getSimpleName(), eoSoftDeleteColumn.getName(), eoPrimaryKeyField.getName()); Query q = getEntityManager().createQuery(sql); q.setParameter("ids", ids); q.setParameter("date", new Timestamp(new Date().getTime()).toString()); q.executeUpdate(); fireSoftDeleteExtension(ids, voClass); fireSoftDeleteExtensionByEOClass(ids, eoClass); }
@Transactional(propagation = Propagation.REQUIRES_NEW) void removeByPrimaryKey(Object id) { if (hasEO()) { softDelete(list(id)); } else { hardDelete(list(id)); } }
@Transactional(propagation = Propagation.REQUIRES_NEW) void remove(Object entity) { if (!hasEO()) { hardDelete(entity); } else { softDelete(entity); } }
private void hardDelete(Object entity) { entity = getEntityManager().merge(entity); getEntityManager().remove(entity); Object idval = getVOPrimaryKeyValue(entity); fireHardDeleteExtension(list(idval)); }