public Query getQuery(AuditReaderImplementor versionsReader, Object primaryKey, Number revision) { Query query = versionsReader.getSession().createQuery(queryString); query.setParameter("revision", revision); query.setParameter("delrevisiontype", RevisionType.DEL); for (QueryParameterData paramData : referencingIdData.getPrefixedMapper().mapToQueryParametersFromId(primaryKey)) { paramData.setParameterValue(query); } return query; }
public ThreeEntityQueryGenerator( GlobalConfiguration globalCfg, AuditEntitiesConfiguration verEntCfg, AuditStrategy auditStrategy, String versionsMiddleEntityName, MiddleIdData referencingIdData, MiddleIdData referencedIdData, MiddleIdData indexIdData, boolean revisionTypeInId, MiddleComponentData... componentDatas) { this.referencingIdData = referencingIdData; /* * The query that we need to create: * SELECT new list(ee, e, f) FROM versionsReferencedEntity e, versionsIndexEntity f, middleEntity ee * WHERE * (entities referenced by the middle table; id_ref_ed = id of the referenced entity) * ee.id_ref_ed = e.id_ref_ed AND * (entities referenced by the middle table; id_ref_ind = id of the index entity) * ee.id_ref_ind = f.id_ref_ind AND * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * ee.id_ref_ing = :id_ref_ing AND * (selecting e entities at revision :revision) * --> for DefaultAuditStrategy: * e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2 * WHERE e2.revision <= :revision AND e2.id = e.id) * * --> for ValidityAuditStrategy: * e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null) * * AND * * (selecting f entities at revision :revision) * --> for DefaultAuditStrategy: * f.revision = (SELECT max(f2.revision) FROM versionsIndexEntity f2 * WHERE f2.revision <= :revision AND f2.id_ref_ed = f.id_ref_ed) * * --> for ValidityAuditStrategy: * f.revision <= :revision and (f.endRevision > :revision or f.endRevision is null) * * AND * * (the association at revision :revision) * --> for DefaultAuditStrategy: * ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2 * WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*) * * --> for ValidityAuditStrategy: * ee.revision <= :revision and (ee.endRevision > :revision or ee.endRevision is null) * and ( strtestent1_.REVEND>? or strtestent1_.REVEND is null ) and ( strtestent1_.REVEND>? or strtestent1_.REVEND is null ) and ( ternarymap0_.REVEND>? or ternarymap0_.REVEND is null ) * * * * (only non-deleted entities and associations) * ee.revision_type != DEL AND * e.revision_type != DEL AND * f.revision_type != DEL */ String revisionPropertyPath = verEntCfg.getRevisionNumberPath(); String originalIdPropertyName = verEntCfg.getOriginalIdPropName(); String eeOriginalIdPropertyPath = "ee." + originalIdPropertyName; // SELECT new list(ee) FROM middleEntity ee QueryBuilder qb = new QueryBuilder(versionsMiddleEntityName, "ee"); qb.addFrom(referencedIdData.getAuditEntityName(), "e"); qb.addFrom(indexIdData.getAuditEntityName(), "f"); qb.addProjection("new list", "ee, e, f", false, false); // WHERE Parameters rootParameters = qb.getRootParameters(); // ee.id_ref_ed = e.id_ref_ed referencedIdData .getPrefixedMapper() .addIdsEqualToQuery( rootParameters, eeOriginalIdPropertyPath, referencedIdData.getOriginalMapper(), "e." + originalIdPropertyName); // ee.id_ref_ind = f.id_ref_ind indexIdData .getPrefixedMapper() .addIdsEqualToQuery( rootParameters, eeOriginalIdPropertyPath, indexIdData.getOriginalMapper(), "f." + originalIdPropertyName); // ee.originalId.id_ref_ing = :id_ref_ing referencingIdData .getPrefixedMapper() .addNamedIdEqualsToQuery(rootParameters, originalIdPropertyName, true); // (selecting e entities at revision :revision) // --> based on auditStrategy (see above) auditStrategy.addEntityAtRevisionRestriction( globalCfg, qb, "e." + revisionPropertyPath, "e." + verEntCfg.getRevisionEndFieldName(), false, referencedIdData, revisionPropertyPath, originalIdPropertyName, "e", "e2"); // (selecting f entities at revision :revision) // --> based on auditStrategy (see above) auditStrategy.addEntityAtRevisionRestriction( globalCfg, qb, "e." + revisionPropertyPath, "e." + verEntCfg.getRevisionEndFieldName(), false, referencedIdData, revisionPropertyPath, originalIdPropertyName, "f", "f2"); // (with ee association at revision :revision) // --> based on auditStrategy (see above) auditStrategy.addAssociationAtRevisionRestriction( qb, revisionPropertyPath, verEntCfg.getRevisionEndFieldName(), true, referencingIdData, versionsMiddleEntityName, eeOriginalIdPropertyPath, revisionPropertyPath, originalIdPropertyName, "ee", componentDatas); // ee.revision_type != DEL final String revisionTypePropName = (revisionTypeInId ? verEntCfg.getOriginalIdPropName() + '.' + verEntCfg.getRevisionTypePropName() : verEntCfg.getRevisionTypePropName()); rootParameters.addWhereWithNamedParam(revisionTypePropName, "!=", "delrevisiontype"); // e.revision_type != DEL rootParameters.addWhereWithNamedParam( "e." + revisionTypePropName, false, "!=", "delrevisiontype"); // f.revision_type != DEL rootParameters.addWhereWithNamedParam( "f." + revisionTypePropName, false, "!=", "delrevisiontype"); StringBuilder sb = new StringBuilder(); qb.build(sb, Collections.<String, Object>emptyMap()); queryString = sb.toString(); }
public TwoEntityOneAuditedQueryGenerator( AuditEntitiesConfiguration verEntCfg, AuditStrategy auditStrategy, String versionsMiddleEntityName, MiddleIdData referencingIdData, MiddleIdData referencedIdData, MiddleComponentData... componentDatas) { this.referencingIdData = referencingIdData; /* * The query that we need to create: * SELECT new list(ee, e) FROM referencedEntity e, middleEntity ee * WHERE * (entities referenced by the middle table; id_ref_ed = id of the referenced entity) * ee.id_ref_ed = e.id_ref_ed AND * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * ee.id_ref_ing = :id_ref_ing AND * * (the association at revision :revision) * --> for DefaultAuditStrategy: * ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2 * WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*) * * --> for ValidTimeAuditStrategy: * ee.revision <= :revision and (ee.endRevision > :revision or ee.endRevision is null) * * AND * * (only non-deleted entities and associations) * ee.revision_type != DEL */ String revisionPropertyPath = verEntCfg.getRevisionNumberPath(); String originalIdPropertyName = verEntCfg.getOriginalIdPropName(); String eeOriginalIdPropertyPath = "ee." + originalIdPropertyName; // SELECT new list(ee) FROM middleEntity ee QueryBuilder qb = new QueryBuilder(versionsMiddleEntityName, "ee"); qb.addFrom(referencedIdData.getEntityName(), "e"); qb.addProjection("new list", "ee, e", false, false); // WHERE Parameters rootParameters = qb.getRootParameters(); // ee.id_ref_ed = e.id_ref_ed referencedIdData .getPrefixedMapper() .addIdsEqualToQuery( rootParameters, eeOriginalIdPropertyPath, referencedIdData.getOriginalMapper(), "e"); // ee.originalId.id_ref_ing = :id_ref_ing referencingIdData .getPrefixedMapper() .addNamedIdEqualsToQuery(rootParameters, originalIdPropertyName, true); // (with ee association at revision :revision) // --> based on auditStrategy (see above) auditStrategy.addAssociationAtRevisionRestriction( qb, revisionPropertyPath, verEntCfg.getRevisionEndFieldName(), true, referencingIdData, versionsMiddleEntityName, eeOriginalIdPropertyPath, revisionPropertyPath, originalIdPropertyName, componentDatas); // ee.revision_type != DEL rootParameters.addWhereWithNamedParam( verEntCfg.getRevisionTypePropName(), "!=", "delrevisiontype"); StringBuilder sb = new StringBuilder(); qb.build(sb, Collections.<String, Object>emptyMap()); queryString = sb.toString(); }
@SuppressWarnings({"unchecked"}) private void addOneToManyAttached(boolean fakeOneToManyBidirectional) { LOG.debugf( "Adding audit mapping for property %s.%s: one-to-many collection, using a join column on the referenced entity", referencingEntityName, propertyName); String mappedBy = getMappedBy(propertyValue); IdMappingData referencedIdMapping = mainGenerator.getReferencedIdMappingData( referencingEntityName, referencedEntityName, propertyAuditingData, false); IdMappingData referencingIdMapping = referencingEntityConfiguration.getIdMappingData(); // Generating the id mappers data for the referencing side of the relation. MiddleIdData referencingIdData = createMiddleIdData(referencingIdMapping, mappedBy + "_", referencingEntityName); // And for the referenced side. The prefixed mapper won't be used (as this collection isn't // persisted // in a join table, so the prefix value is arbitrary). MiddleIdData referencedIdData = createMiddleIdData(referencedIdMapping, null, referencedEntityName); // Generating the element mapping. MiddleComponentData elementComponentData = new MiddleComponentData(new MiddleRelatedComponentMapper(referencedIdData), 0); // Generating the index mapping, if an index exists. It can only exists in case a // javax.persistence.MapKey // annotation is present on the entity. So the middleEntityXml will be not be used. The // queryGeneratorBuilder // will only be checked for nullnes. MiddleComponentData indexComponentData = addIndex(null, null); // Generating the query generator - it should read directly from the related entity. RelationQueryGenerator queryGenerator = new OneAuditEntityQueryGenerator( mainGenerator.getGlobalCfg(), mainGenerator.getVerEntCfg(), mainGenerator.getAuditStrategy(), referencingIdData, referencedEntityName, referencedIdData); // Creating common mapper data. CommonCollectionMapperData commonCollectionMapperData = new CommonCollectionMapperData( mainGenerator.getVerEntCfg(), referencedEntityName, propertyAuditingData.getPropertyData(), referencingIdData, queryGenerator); PropertyMapper fakeBidirectionalRelationMapper; PropertyMapper fakeBidirectionalRelationIndexMapper; if (fakeOneToManyBidirectional) { // In case of a fake many-to-one bidirectional relation, we have to generate a mapper which // maps // the mapped-by property name to the id of the related entity (which is the owner of the // collection). String auditMappedBy = propertyAuditingData.getAuditMappedBy(); // Creating a prefixed relation mapper. IdMapper relMapper = referencingIdMapping .getIdMapper() .prefixMappedProperties(MappingTools.createToOneRelationPrefix(auditMappedBy)); fakeBidirectionalRelationMapper = new ToOneIdMapper( relMapper, // The mapper will only be used to map from entity to map, so no need to provide other // details // when constructing the PropertyData. new PropertyData(auditMappedBy, null, null, null), referencingEntityName, false); // Checking if there's an index defined. If so, adding a mapper for it. if (propertyAuditingData.getPositionMappedBy() != null) { String positionMappedBy = propertyAuditingData.getPositionMappedBy(); fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper(new PropertyData(positionMappedBy, null, null, null)); // Also, overwriting the index component data to properly read the index. indexComponentData = new MiddleComponentData(new MiddleStraightComponentMapper(positionMappedBy), 0); } else { fakeBidirectionalRelationIndexMapper = null; } } else { fakeBidirectionalRelationMapper = null; fakeBidirectionalRelationIndexMapper = null; } // Checking the type of the collection and adding an appropriate mapper. addMapper(commonCollectionMapperData, elementComponentData, indexComponentData); // Storing information about this relation. referencingEntityConfiguration.addToManyNotOwningRelation( propertyName, mappedBy, referencedEntityName, referencingIdData.getPrefixedMapper(), fakeBidirectionalRelationMapper, fakeBidirectionalRelationIndexMapper); }