All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.blazebit.persistence.view.impl.entity.InverseEntityToEntityMapper Maven / Gradle / Ivy

There is a newer version: 1.6.11
Show newest version
/*
 * Copyright 2014 - 2020 Blazebit.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.blazebit.persistence.view.impl.entity;

import com.blazebit.persistence.parser.util.JpaMetamodelUtils;
import com.blazebit.persistence.view.impl.EntityViewManagerImpl;
import com.blazebit.persistence.view.impl.accessor.AttributeAccessor;
import com.blazebit.persistence.view.impl.mapper.Mapper;
import com.blazebit.persistence.view.impl.update.UpdateContext;
import com.blazebit.persistence.view.impl.update.flush.DirtyAttributeFlusher;

import javax.persistence.Query;
import javax.persistence.metamodel.EntityType;

/**
 *
 * @author Christian Beikov
 * @since 1.2.0
 */
public class InverseEntityToEntityMapper implements InverseElementToEntityMapper {

    private static final String ID_PARAM_NAME = "_id";
    private final String updatePrefixString;
    private final String updatePostfixString;
    private final String fullUpdateQueryString;
    private final AttributeAccessor entityIdAccessor;
    private final DirtyAttributeFlusher inverseAttributeFlusher;
    private final Mapper parentEntityOnChildEntityAddMapper;
    private final Mapper parentEntityOnChildEntityRemoveMapper;

    public InverseEntityToEntityMapper(EntityViewManagerImpl evm, EntityType entityType, Mapper parentEntityOnChildEntityAddMapper, Mapper parentEntityOnChildEntityRemoveMapper, DirtyAttributeFlusher inverseAttributeFlusher) {
        this.updatePrefixString = "UPDATE " + entityType.getName() + " e SET ";
        this.updatePostfixString = " WHERE e." + JpaMetamodelUtils.getSingleIdAttribute(entityType).getName() + " = :" + ID_PARAM_NAME;
        this.parentEntityOnChildEntityAddMapper = parentEntityOnChildEntityAddMapper;
        this.parentEntityOnChildEntityRemoveMapper = parentEntityOnChildEntityRemoveMapper;
        this.inverseAttributeFlusher = inverseAttributeFlusher;
        this.fullUpdateQueryString = createQueryString(null, inverseAttributeFlusher);
        this.entityIdAccessor = evm.getEntityIdAccessor();
    }

    private String createQueryString(DirtyAttributeFlusher nestedGraphNode, DirtyAttributeFlusher inverseAttributeFlusher) {
        StringBuilder sb = new StringBuilder(updatePrefixString.length() + updatePostfixString.length() + 250);
        sb.append(updatePrefixString);
        inverseAttributeFlusher.appendUpdateQueryFragment(null, sb, "e.", "", ", ");

        if (nestedGraphNode != null) {
            sb.append(", ");
            int initialLength = sb.length();
            nestedGraphNode.appendUpdateQueryFragment(null, sb, "e.", "", ", ");

            if (sb.length() == initialLength) {
                sb.setLength(sb.length() - 2);
                sb.append(updatePostfixString);
                return sb.toString();
            } else {
                sb.append(updatePostfixString);
                return sb.toString();
            }
        }

        sb.append(updatePostfixString);
        return sb.toString();
    }

    @Override
    public void flushEntity(UpdateContext context, Object oldParent, Object newParent, Object child, DirtyAttributeFlusher nestedGraphNode) {
        // Set the "newParent" on the entity object "child"
        if (newParent == null) {
            parentEntityOnChildEntityRemoveMapper.map(oldParent, child);
        } else {
            parentEntityOnChildEntityAddMapper.map(newParent, child);
        }

        if (nestedGraphNode != null) {
            nestedGraphNode.flushEntity(context, null, child, null, child, null);
        }
    }

    @Override
    public Query createInverseUpdateQuery(UpdateContext context, Object element, DirtyAttributeFlusher nestedGraphNode, DirtyAttributeFlusher inverseAttributeFlusher) {
        String queryString;
        if (inverseAttributeFlusher == this.inverseAttributeFlusher && nestedGraphNode == null) {
            queryString = fullUpdateQueryString;
        } else {
            queryString = createQueryString(nestedGraphNode, inverseAttributeFlusher);
        }

        Query query = null;
        if (queryString != null) {
            query = context.getEntityManager().createQuery(queryString);
            query.setParameter(ID_PARAM_NAME, entityIdAccessor.getValue(element));
        }

        return query;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy