/** * Creates a snapshot of the entity. * * @since 2.0.0 */ private void snapshot() { ManagedInstance.LOG.trace("Snapshot generated for instance {0}", this); if (this.snapshot.size() == 0) { for (final AbstractMapping<?, ?, ?> mapping : this.type.getMappingsSingular()) { this.snapshot.put(mapping, mapping.get(this.instance)); } } }
/** * Sets the status. * * @param status the status to set * @since 2.0.0 */ public void setStatus(Status status) { this.oldStatus = this.status; if (status != this.status) { ManagedInstance.LOG.debug( "Instance status changing for {0}: {1} -> {2}", this, this.status, status); this.status = status; } }
/** * Resets the change status of the instance. * * @since 2.0.0 */ public void reset() { ManagedInstance.LOG.trace("Reset instance {0}", this); this.collectionsChanged.clear(); this.changed = false; this.snapshot.clear(); this.snapshot(); }
/** * Handles the entities that have been orphaned. * * @param entityManager the entity manager * @since 2.0.0 */ public void handleOrphans(EntityManagerImpl entityManager) { ManagedInstance.LOG.debug("Inspecting orphans for instance {0}", this); for (int i = 0; i < this.collectionsChanged.size(); i++) { final PluralMappingEx<?, ?, ?> collection = this.collectionsChanged.get(i); if (collection.isAssociation()) { ((PluralAssociationMappingImpl<?, ?, ?>) collection).removeOrphans(entityManager, this); } } }
/** * Flushes the associations. * * @param connection the connection * @param removals true if the removals should be flushed and false for the additions * @param force true to force, effective only for insertions and for new entities. * @throws SQLException thrown if there is an underlying SQL Exception * @since 2.0.0 */ public void flushAssociations(Connection connection, boolean removals, boolean force) throws SQLException { if (!removals || (this.status != Status.NEW)) { ManagedInstance.LOG.debug("Flushing associations for instance {0}", this); for (final JoinedMapping<?, ?, ?> collection : this.type.getMappingsJoined()) { collection.flush(connection, this, removals, force); } } }
/** * Handles the entities that have been added. * * @param entityManager the entity manager * @since 2.0.0 */ public void handleAdditions(EntityManagerImpl entityManager) { ManagedInstance.LOG.debug("Inspecting additions for instance {0}", this); for (int i = 0; i < this.collectionsChanged.size(); i++) { final PluralMappingEx<?, ?, ?> collection = this.collectionsChanged.get(i); if (collection instanceof PluralAssociationMappingImpl) { ((PluralAssociationMappingImpl<?, ?, ?>) collection).persistAdditions(entityManager, this); } } }
/** * Refreshes the instance from the database. * * @param entityManager the entity manager * @param connection the connection * @param lockMode the lock mode * @param processed the set of processed instances * @since 2.0.0 */ public void refresh( EntityManagerImpl entityManager, Connection connection, LockModeType lockMode, Set<Object> processed) { ManagedInstance.LOG.debug("Refeshing instance {0}", this); this.type.performRefresh(connection, this, lockMode, processed); for (final AssociationMappingImpl<?, ?, ?> association : this.type.getAssociations()) { association.refresh(this, processed); } }
/** * Cascades the remove operation * * @param entityManager the entity manager * @param processed registry of processed entities * @param instances the managed instances * @since 2.0.0 */ public void cascadeRemove( EntityManagerImpl entityManager, ArrayList<Object> processed, LinkedList<ManagedInstance<?>> instances) { ManagedInstance.LOG.debug("Cascading remove on {0}", this); for (final AssociationMappingImpl<?, ?, ?> association : this.type.getAssociationsRemovable()) { // if the association a collection attribute then we will cascade to each element if (association instanceof PluralAssociationMappingImpl) { final PluralAssociationMappingImpl<?, ?, ?> mapping = (PluralAssociationMappingImpl<?, ?, ?>) association; // extract the collection final Collection<?> collection; if (mapping.getAttribute().getCollectionType() == CollectionType.MAP) { collection = ((Map<?, ?>) mapping.get(this.instance)).values(); } else { collection = (Collection<?>) mapping.get(this.instance); } // cascade to each element in the collection if (collection instanceof List) { final List<?> list = (List<?>) collection; for (int i = 0; i < list.size(); i++) { entityManager.removeImpl(list.get(i), processed, instances); } } else { for (final Object element : collection) { entityManager.removeImpl(element, processed, instances); } } } else { final SingularAssociationMappingImpl<?, ?> mapping = (SingularAssociationMappingImpl<?, ?>) association; final Object associate = mapping.get(this.instance); if (associate != null) { entityManager.removeImpl(associate, processed, instances); } } } }
/** * Cascades the detach operation. * * @param entityManager the entity manager * @since 2.0.0 */ public void cascadeDetach(EntityManagerImpl entityManager) { this.status = Status.DETACHED; ManagedInstance.LOG.debug("Cascading detach on {0}", this); for (final AssociationMappingImpl<?, ?, ?> association : this.type.getAssociationsDetachable()) { // if the association a collection attribute then we will cascade to each element if (association instanceof PluralAssociationMappingImpl) { final PluralAssociationMappingImpl<?, ?, ?> mapping = (PluralAssociationMappingImpl<?, ?, ?>) association; final Collection<?> collection; if (mapping.getAttribute().getCollectionType() == CollectionType.MAP) { collection = ((Map<?, ?>) mapping.get(this.instance)).values(); } else { // extract the collection collection = (Collection<?>) mapping.get(this.instance); } // cascade to each element in the collection if (collection instanceof List) { final List<?> list = (List<?>) collection; for (int i = 0; i < list.size(); i++) { entityManager.detach(list.get(i)); } } else { for (final Object element : collection) { entityManager.detach(element); } } } else { final SingularAssociationMappingImpl<?, ?> mapping = (SingularAssociationMappingImpl<?, ?>) association; final Object associate = mapping.get(this.instance); entityManager.detach(associate); } } }
/** * Processes the associations. * * @since 2.0.0 */ public void processJoinedMappings() { ManagedInstance.LOG.debug("Post processing associations for instance {0}", this); final HashSet<String> _joinsLoaded = this.joinsLoaded; for (final PluralMappingEx<?, ?, ?> mapping : this.type.getMappingsPlural()) { final HashSet<String> joinsLoaded2 = _joinsLoaded; if (!joinsLoaded2.contains(mapping.getPath())) { if (mapping.isEager()) { mapping.load(this); } else { mapping.setLazy(this); } } } final X _instance = this.instance; final EntityManagerImpl entityManager = this.session.getEntityManager(); for (final SingularAssociationMappingImpl<?, ?> mapping : this.type.getAssociationsSingular()) { if (mapping.isEager()) { if (!_joinsLoaded.contains(mapping.getPath())) { mapping.initialize(this); } else { final Object associate = mapping.get(_instance); if (associate instanceof EnhancedInstance) { final EnhancedInstance enhancedInstance = (EnhancedInstance) associate; if (!enhancedInstance.__enhanced__$$__isInitialized()) { final ManagedInstance<?> associateManagedInstance = enhancedInstance.__enhanced__$$__getManagedInstance(); entityManager.find( associateManagedInstance.getType().getJavaType(), associateManagedInstance.getId().getId()); } } } } } }
/** * Increments the version of the instance. * * @param connection the connection * @param commit true if version update should be committed immediately * @throws SQLException thrown in case of an underlying SQL error * @since 2.0.0 */ public void incrementVersion(Connection connection, boolean commit) throws SQLException { if (!this.type.getRootType().hasVersionAttribute()) { return; } final EntityTypeImpl<? super X> rootType = this.type.getRootType(); final BasicAttribute<? super X, ?> version = rootType.getVersionAttribute(); if (this.oldVersion == null) { switch (this.type.getVersionType()) { case SHORT: final short shortValue = (((Number) version.get(this.instance)).shortValue()); this.oldVersion = shortValue; version.set(this.instance, shortValue + 1); ManagedInstance.LOG.debug("Version upgraded instance: {0} - {1}", this, shortValue); break; case SHORT_OBJECT: final Short shortObjValue = version.get(this.instance) == null ? 0 : // Short.valueOf((((Number) version.get(this.instance)).shortValue())); this.oldVersion = shortObjValue; version.set(this.instance, shortObjValue + 1); ManagedInstance.LOG.debug("Version upgraded instance: {0} - {1}", this, shortObjValue); break; case INT: final int intValue = (((Number) version.get(this.instance)).intValue()); this.oldVersion = intValue; version.set(this.instance, intValue + 1); ManagedInstance.LOG.debug("Version upgraded instance: {0} - {1}", this, intValue); break; case INT_OBJECT: final Integer intObjValue = version.get(this.instance) == null ? 0 : // Integer.valueOf(((Number) version.get(this.instance)).intValue()); this.oldVersion = intObjValue; version.set(this.instance, intObjValue + 1); ManagedInstance.LOG.debug("Version upgraded instance: {0} - {1}", this, intObjValue); break; case LONG: final long longValue = (((Number) version.get(this.instance)).longValue()); this.oldVersion = longValue; version.set(this.instance, longValue + 1); ManagedInstance.LOG.debug("Version upgraded instance: {0} - {1}", this, longValue); break; case LONG_OBJECT: final Long longObjValue = version.get(this.instance) == null ? 0l : // Long.valueOf((((Number) version.get(this.instance)).longValue())); this.oldVersion = longObjValue; version.set(this.instance, longObjValue + 1); ManagedInstance.LOG.debug("Version upgraded instance: {0} - {1}", this, longObjValue); break; case TIMESTAMP: final Timestamp value = new Timestamp(System.currentTimeMillis()); this.oldVersion = version.get(this.instance); version.set(this.instance, value); ManagedInstance.LOG.debug("Version upgraded instance: {0} - {1}", this, value); } } if (commit) { final Object newVersion = version.get(this.instance); rootType.performVersionUpdate(connection, this, this.oldVersion, newVersion); ManagedInstance.LOG.debug( "Version committed instance: {0} - {1} -> {2}", this, this.oldVersion, newVersion); this.oldVersion = null; } else { this.changed(); } }
/** * Fills the sequence / table generated values. The operation returns false if at least one entity * needs to obtain identity from the database. * * @return false if all OK, true if if at least one entity needs to obtain identity from the * database * @since 2.0.0 */ public boolean fillIdValues() { ManagedInstance.LOG.debug("Auto generating id values for {0}", this); return this.hasInitialId = this.fillValuesImpl(); }
/** * Cascades the persist operation. * * @param entityManager the entity manager * @param processed registry of processed entities * @param instances the managed instances * @return true if an implicit flush is required, false otherwise * @since 2.0.0 */ public boolean cascadePersist( EntityManagerImpl entityManager, ArrayList<Object> processed, LinkedList<ManagedInstance<?>> instances) { ManagedInstance.LOG.debug("Cascading persist on {0}", this); boolean requiresFlush = false; for (final AssociationMappingImpl<?, ?, ?> association : this.type.getAssociationsPersistable()) { // if the association a collection attribute then we will cascade to each element if (association instanceof PluralAssociationMappingImpl) { final PluralAssociationMappingImpl<?, ?, ?> mapping = (PluralAssociationMappingImpl<?, ?, ?>) association; switch (mapping.getAttribute().getCollectionType()) { case MAP: // extract the map final Map<?, ?> map = (Map<?, ?>) mapping.get(this.instance); // cascade to each element in the map for (final Object element : map.values()) { requiresFlush |= entityManager.persistImpl(element, processed, instances); } break; case LIST: // extract the list final List<?> list = (List<?>) mapping.get(this.instance); // cascade to each element in the list for (int i = 0; i < list.size(); i++) { requiresFlush |= entityManager.persistImpl(list.get(i), processed, instances); } break; default: // extract the collection final Collection<?> collection = (Collection<?>) mapping.get(this.instance); // cascade to each element in the collection if (collection instanceof List) { final List<?> castedList = (List<?>) collection; for (int i = 0; i < castedList.size(); i++) { requiresFlush |= entityManager.persistImpl(castedList.get(i), processed, instances); } } else { for (final Object element : collection) { requiresFlush |= entityManager.persistImpl(element, processed, instances); } } break; } } else { final SingularAssociationMappingImpl<?, ?> mapping = (SingularAssociationMappingImpl<?, ?>) association; final Object associate = mapping.get(this.instance); if (associate != null) { requiresFlush |= entityManager.persistImpl(associate, processed, instances); } } } return requiresFlush; }