HHH-7841 - Redesign Loader
This commit is contained in:
parent
c259e157b0
commit
a102bf2c31
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine;
|
||||
|
||||
/**
|
||||
* Describes the strategy for fetching an association
|
||||
* <p/>
|
||||
* todo not really a fan of the name. not sure of a better one though.
|
||||
* I'd almost rather see this be called the style, but then what to call FetchStyle? HowToFetch?
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class FetchStrategy {
|
||||
private final FetchTiming timing;
|
||||
private final FetchStyle style;
|
||||
|
||||
public FetchStrategy(FetchTiming timing, FetchStyle style) {
|
||||
this.timing = timing;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public FetchTiming getTiming() {
|
||||
return timing;
|
||||
}
|
||||
|
||||
public FetchStyle getStyle() {
|
||||
return style;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.internal;
|
||||
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.CascadingAction;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||
|
||||
/**
|
||||
* A LoadPlan building strategy for cascade processing; meaning, it builds the LoadPlan for loading related to
|
||||
* cascading a particular action across associations
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CascadeLoadPlanBuilderStrategy extends SingleRootReturnLoadPlanBuilderStrategy {
|
||||
private static final FetchStrategy EAGER = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
||||
private static final FetchStrategy DELAYED = new FetchStrategy( FetchTiming.DELAYED, FetchStyle.SELECT );
|
||||
|
||||
private final CascadingAction cascadeActionToMatch;
|
||||
|
||||
public CascadeLoadPlanBuilderStrategy(
|
||||
CascadingAction cascadeActionToMatch,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
LoadQueryInfluencers loadQueryInfluencers,
|
||||
String rootAlias,
|
||||
int suffixSeed) {
|
||||
super( sessionFactory, loadQueryInfluencers, rootAlias, suffixSeed );
|
||||
this.cascadeActionToMatch = cascadeActionToMatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FetchStrategy determineFetchPlan(AssociationAttributeDefinition attributeDefinition) {
|
||||
return attributeDefinition.determineCascadeStyle().doCascade( cascadeActionToMatch ) ? EAGER : DELAYED;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.loader.plan.spi.LoadPlan;
|
||||
import org.hibernate.loader.plan.spi.Return;
|
||||
|
||||
/**
|
||||
* Implementation of LoadPlan.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LoadPlanImpl implements LoadPlan {
|
||||
private final boolean hasScalars;
|
||||
private final List<Return> returns;
|
||||
|
||||
public LoadPlanImpl(boolean hasScalars, List<Return> returns) {
|
||||
this.hasScalars = hasScalars;
|
||||
this.returns = returns;
|
||||
}
|
||||
|
||||
public LoadPlanImpl(boolean hasScalars, Return rootReturn) {
|
||||
this( hasScalars, Collections.singletonList( rootReturn ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnyScalarReturns() {
|
||||
return hasScalars;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Return> getReturns() {
|
||||
return returns;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.internal;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.loader.CollectionAliases;
|
||||
import org.hibernate.loader.DefaultEntityAliases;
|
||||
import org.hibernate.loader.EntityAliases;
|
||||
import org.hibernate.loader.GeneratedCollectionAliases;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
import org.hibernate.loader.plan.spi.AbstractFetchOwner;
|
||||
import org.hibernate.loader.plan.spi.AbstractLoadPlanBuilderStrategy;
|
||||
import org.hibernate.loader.plan.spi.CollectionFetch;
|
||||
import org.hibernate.loader.plan.spi.CollectionReturn;
|
||||
import org.hibernate.loader.plan.spi.CompositeFetch;
|
||||
import org.hibernate.loader.plan.spi.EntityFetch;
|
||||
import org.hibernate.loader.plan.spi.EntityReturn;
|
||||
import org.hibernate.loader.plan.spi.FetchOwner;
|
||||
import org.hibernate.loader.plan.spi.LoadPlan;
|
||||
import org.hibernate.loader.plan.spi.LoadPlanBuilderStrategy;
|
||||
import org.hibernate.loader.plan.spi.Return;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.Loadable;
|
||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.CompositeDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* LoadPlanBuilderStrategy implementation used for building LoadPlans with a single processing RootEntity LoadPlan building.
|
||||
*
|
||||
* Really this is a single-root LoadPlan building strategy for building LoadPlans for:<ul>
|
||||
* <li>entity load plans</li>
|
||||
* <li>cascade load plans</li>
|
||||
* <li>collection initializer plans</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SingleRootReturnLoadPlanBuilderStrategy
|
||||
extends AbstractLoadPlanBuilderStrategy
|
||||
implements LoadPlanBuilderStrategy {
|
||||
|
||||
private final LoadQueryInfluencers loadQueryInfluencers;
|
||||
|
||||
private final String rootAlias;
|
||||
private int currentSuffixBase;
|
||||
|
||||
private Return rootReturn;
|
||||
|
||||
private PropertyPath propertyPath = new PropertyPath( "" );
|
||||
|
||||
public SingleRootReturnLoadPlanBuilderStrategy(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
LoadQueryInfluencers loadQueryInfluencers,
|
||||
String rootAlias,
|
||||
int suffixSeed) {
|
||||
super( sessionFactory );
|
||||
this.loadQueryInfluencers = loadQueryInfluencers;
|
||||
this.rootAlias = rootAlias;
|
||||
this.currentSuffixBase = suffixSeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsRootEntityReturns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsRootCollectionReturns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addRootReturn(Return rootReturn) {
|
||||
if ( this.rootReturn != null ) {
|
||||
throw new HibernateException( "Root return already identified" );
|
||||
}
|
||||
this.rootReturn = rootReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadPlan buildLoadPlan() {
|
||||
return new LoadPlanImpl( false, rootReturn );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FetchStrategy determineFetchPlan(AssociationAttributeDefinition attributeDefinition) {
|
||||
FetchStrategy fetchStrategy = attributeDefinition.determineFetchPlan( loadQueryInfluencers, propertyPath );
|
||||
if ( fetchStrategy.getTiming() == FetchTiming.IMMEDIATE && fetchStrategy.getStyle() == FetchStyle.JOIN ) {
|
||||
// see if we need to alter the join fetch to another form for any reason
|
||||
fetchStrategy = adjustJoinFetchIfNeeded( attributeDefinition, fetchStrategy );
|
||||
}
|
||||
return fetchStrategy;
|
||||
}
|
||||
|
||||
protected FetchStrategy adjustJoinFetchIfNeeded(
|
||||
AssociationAttributeDefinition attributeDefinition,
|
||||
FetchStrategy fetchStrategy) {
|
||||
if ( currentDepth() > sessionFactory().getSettings().getMaximumFetchDepth() ) {
|
||||
return new FetchStrategy( fetchStrategy.getTiming(), FetchStyle.SELECT );
|
||||
}
|
||||
|
||||
if ( attributeDefinition.getType().isCollectionType() && isTooManyCollections() ) {
|
||||
// todo : have this revert to batch or subselect fetching once "sql gen redesign" is in place
|
||||
return new FetchStrategy( fetchStrategy.getTiming(), FetchStyle.SELECT );
|
||||
}
|
||||
|
||||
return fetchStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isTooManyCollections() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityReturn buildRootEntityReturn(EntityDefinition entityDefinition) {
|
||||
final String entityName = entityDefinition.getEntityPersister().getEntityName();
|
||||
return new EntityReturn(
|
||||
sessionFactory(),
|
||||
rootAlias,
|
||||
LockMode.NONE, // todo : for now
|
||||
entityName,
|
||||
StringHelper.generateAlias( StringHelper.unqualifyEntityName( entityName ), currentDepth() ),
|
||||
new DefaultEntityAliases(
|
||||
(Loadable) entityDefinition.getEntityPersister(),
|
||||
Integer.toString( currentSuffixBase++ ) + '_'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CollectionReturn buildRootCollectionReturn(CollectionDefinition collectionDefinition) {
|
||||
final CollectionPersister persister = collectionDefinition.getCollectionPersister();
|
||||
final String collectionRole = persister.getRole();
|
||||
|
||||
final CollectionAliases collectionAliases = new GeneratedCollectionAliases(
|
||||
collectionDefinition.getCollectionPersister(),
|
||||
Integer.toString( currentSuffixBase++ ) + '_'
|
||||
);
|
||||
final Type elementType = collectionDefinition.getCollectionPersister().getElementType();
|
||||
final EntityAliases elementAliases;
|
||||
if ( elementType.isEntityType() ) {
|
||||
final EntityType entityElementType = (EntityType) elementType;
|
||||
elementAliases = new DefaultEntityAliases(
|
||||
(Loadable) entityElementType.getAssociatedJoinable( sessionFactory() ),
|
||||
Integer.toString( currentSuffixBase++ ) + '_'
|
||||
);
|
||||
}
|
||||
else {
|
||||
elementAliases = null;
|
||||
}
|
||||
|
||||
return new CollectionReturn(
|
||||
sessionFactory(),
|
||||
rootAlias,
|
||||
LockMode.NONE, // todo : for now
|
||||
persister.getOwnerEntityPersister().getEntityName(),
|
||||
StringHelper.unqualify( collectionRole ),
|
||||
collectionAliases,
|
||||
elementAliases
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CollectionFetch buildCollectionFetch(
|
||||
FetchOwner fetchOwner,
|
||||
AssociationAttributeDefinition attributeDefinition,
|
||||
FetchStrategy fetchStrategy) {
|
||||
final CollectionDefinition collectionDefinition = attributeDefinition.toCollectionDefinition();
|
||||
final CollectionAliases collectionAliases = new GeneratedCollectionAliases(
|
||||
collectionDefinition.getCollectionPersister(),
|
||||
Integer.toString( currentSuffixBase++ ) + '_'
|
||||
);
|
||||
final Type elementType = collectionDefinition.getCollectionPersister().getElementType();
|
||||
final EntityAliases elementAliases;
|
||||
if ( elementType.isEntityType() ) {
|
||||
final EntityType entityElementType = (EntityType) elementType;
|
||||
elementAliases = new DefaultEntityAliases(
|
||||
(Loadable) entityElementType.getAssociatedJoinable( sessionFactory() ),
|
||||
Integer.toString( currentSuffixBase++ ) + '_'
|
||||
);
|
||||
}
|
||||
else {
|
||||
elementAliases = null;
|
||||
}
|
||||
|
||||
return new CollectionFetch(
|
||||
sessionFactory(),
|
||||
createImplicitAlias(),
|
||||
LockMode.NONE, // todo : for now
|
||||
(AbstractFetchOwner) fetchOwner,
|
||||
fetchStrategy,
|
||||
attributeDefinition.getName(),
|
||||
collectionAliases,
|
||||
elementAliases
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityFetch buildEntityFetch(
|
||||
FetchOwner fetchOwner,
|
||||
AssociationAttributeDefinition attributeDefinition,
|
||||
FetchStrategy fetchStrategy) {
|
||||
final EntityDefinition entityDefinition = attributeDefinition.toEntityDefinition();
|
||||
|
||||
return new EntityFetch(
|
||||
sessionFactory(),
|
||||
createImplicitAlias(),
|
||||
LockMode.NONE, // todo : for now
|
||||
(AbstractFetchOwner) fetchOwner,
|
||||
attributeDefinition.getName(),
|
||||
fetchStrategy,
|
||||
StringHelper.generateAlias( entityDefinition.getEntityPersister().getEntityName(), currentDepth() ),
|
||||
new DefaultEntityAliases(
|
||||
(Loadable) entityDefinition.getEntityPersister(),
|
||||
Integer.toString( currentSuffixBase++ ) + '_'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompositeFetch buildCompositeFetch(FetchOwner fetchOwner, CompositeDefinition attributeDefinition) {
|
||||
return new CompositeFetch(
|
||||
sessionFactory(),
|
||||
createImplicitAlias(),
|
||||
(AbstractFetchOwner) fetchOwner,
|
||||
attributeDefinition.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private int implicitAliasUniqueness = 0;
|
||||
|
||||
private String createImplicitAlias() {
|
||||
return "ia" + implicitAliasUniqueness++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractFetch extends AbstractFetchOwner implements Fetch {
|
||||
private final FetchOwner owner;
|
||||
private final String ownerProperty;
|
||||
private final FetchStrategy fetchStrategy;
|
||||
|
||||
private final PropertyPath propertyPath;
|
||||
|
||||
public AbstractFetch(
|
||||
SessionFactoryImplementor factory,
|
||||
String alias,
|
||||
LockMode lockMode,
|
||||
AbstractFetchOwner owner,
|
||||
String ownerProperty,
|
||||
FetchStrategy fetchStrategy) {
|
||||
super( factory, alias, lockMode );
|
||||
this.owner = owner;
|
||||
this.ownerProperty = ownerProperty;
|
||||
this.fetchStrategy = fetchStrategy;
|
||||
|
||||
owner.addFetch( this );
|
||||
|
||||
this.propertyPath = owner.getPropertyPath().append( ownerProperty );
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchOwner getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOwnerPropertyName() {
|
||||
return ownerProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchStrategy getFetchStrategy() {
|
||||
return fetchStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateFetchPlan(FetchStrategy fetchStrategy) {
|
||||
if ( fetchStrategy.getStyle() == FetchStyle.JOIN ) {
|
||||
if ( this.fetchStrategy.getStyle() != FetchStyle.JOIN ) {
|
||||
throw new HibernateException( "Cannot specify join fetch from owner that is a non-joined fetch" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyPath getPropertyPath() {
|
||||
return propertyPath;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractFetchOwner extends AbstractPlanNode implements FetchOwner {
|
||||
private final String alias;
|
||||
private final LockMode lockMode;
|
||||
|
||||
private List<Fetch> fetches;
|
||||
|
||||
public AbstractFetchOwner(SessionFactoryImplementor factory, String alias, LockMode lockMode) {
|
||||
super( factory );
|
||||
this.alias = alias;
|
||||
if ( alias == null ) {
|
||||
throw new HibernateException( "alias must be specified" );
|
||||
}
|
||||
this.lockMode = lockMode;
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public LockMode getLockMode() {
|
||||
return lockMode;
|
||||
}
|
||||
|
||||
void addFetch(Fetch fetch) {
|
||||
if ( fetch.getOwner() != this ) {
|
||||
throw new IllegalArgumentException( "Fetch and owner did not match" );
|
||||
}
|
||||
|
||||
if ( fetches == null ) {
|
||||
fetches = new ArrayList<Fetch>();
|
||||
}
|
||||
|
||||
fetches.add( fetch );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetch[] getFetches() {
|
||||
return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.CompositeDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilderStrategy {
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
private ArrayDeque<FetchOwner> fetchOwnerStack = new ArrayDeque<FetchOwner>();
|
||||
|
||||
protected AbstractLoadPlanBuilderStrategy(SessionFactoryImplementor sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
public SessionFactoryImplementor sessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
protected FetchOwner currentFetchOwner() {
|
||||
return fetchOwnerStack.peekLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingEntity(EntityDefinition entityDefinition) {
|
||||
if ( fetchOwnerStack.isEmpty() ) {
|
||||
// this is a root...
|
||||
if ( ! supportsRootEntityReturns() ) {
|
||||
throw new HibernateException( "This strategy does not support root entity returns" );
|
||||
}
|
||||
final EntityReturn entityReturn = buildRootEntityReturn( entityDefinition );
|
||||
addRootReturn( entityReturn );
|
||||
fetchOwnerStack.push( entityReturn );
|
||||
}
|
||||
// otherwise this call should represent a fetch which should have been handled in #startingAttribute
|
||||
}
|
||||
|
||||
protected boolean supportsRootEntityReturns() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract void addRootReturn(Return rootReturn);
|
||||
|
||||
@Override
|
||||
public void finishingEntity(EntityDefinition entityDefinition) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingCollection(CollectionDefinition collectionDefinition) {
|
||||
if ( fetchOwnerStack.isEmpty() ) {
|
||||
// this is a root...
|
||||
if ( ! supportsRootCollectionReturns() ) {
|
||||
throw new HibernateException( "This strategy does not support root collection returns" );
|
||||
}
|
||||
final CollectionReturn collectionReturn = buildRootCollectionReturn( collectionDefinition );
|
||||
addRootReturn( collectionReturn );
|
||||
fetchOwnerStack.push( collectionReturn );
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean supportsRootCollectionReturns() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingCollection(CollectionDefinition collectionDefinition) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingComposite(CompositeDefinition compositeDefinition) {
|
||||
if ( fetchOwnerStack.isEmpty() ) {
|
||||
throw new HibernateException( "A component cannot be the root of a walk nor a graph" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingComposite(CompositeDefinition compositeDefinition) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startingAttribute(AttributeDefinition attributeDefinition) {
|
||||
final Type attributeType = attributeDefinition.getType();
|
||||
|
||||
final boolean isComponentType = attributeType.isComponentType();
|
||||
final boolean isBasicType = ! ( isComponentType || attributeType.isAssociationType() );
|
||||
|
||||
if ( isBasicType ) {
|
||||
return true;
|
||||
}
|
||||
else if ( isComponentType ) {
|
||||
return handleCompositeAttribute( (CompositeDefinition) attributeDefinition );
|
||||
}
|
||||
else {
|
||||
return handleAssociationAttribute( (AssociationAttributeDefinition) attributeDefinition );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void finishingAttribute(AttributeDefinition attributeDefinition) {
|
||||
final Type attributeType = attributeDefinition.getType();
|
||||
|
||||
final boolean isComponentType = attributeType.isComponentType();
|
||||
final boolean isBasicType = ! ( isComponentType || attributeType.isAssociationType() );
|
||||
|
||||
if ( ! isBasicType ) {
|
||||
fetchOwnerStack.removeLast();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean handleCompositeAttribute(CompositeDefinition attributeDefinition) {
|
||||
final FetchOwner fetchOwner = fetchOwnerStack.peekLast();
|
||||
final CompositeFetch fetch = buildCompositeFetch( fetchOwner, attributeDefinition );
|
||||
fetchOwnerStack.addLast( fetch );
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean handleAssociationAttribute(AssociationAttributeDefinition attributeDefinition) {
|
||||
final FetchStrategy fetchStrategy = determineFetchPlan( attributeDefinition );
|
||||
if ( fetchStrategy.getTiming() != FetchTiming.IMMEDIATE ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final FetchOwner fetchOwner = fetchOwnerStack.peekLast();
|
||||
fetchOwner.validateFetchPlan( fetchStrategy );
|
||||
|
||||
final Fetch associationFetch;
|
||||
if ( attributeDefinition.isCollection() ) {
|
||||
associationFetch = buildCollectionFetch( fetchOwner, attributeDefinition, fetchStrategy );
|
||||
}
|
||||
else {
|
||||
associationFetch = buildEntityFetch( fetchOwner, attributeDefinition, fetchStrategy );
|
||||
}
|
||||
fetchOwnerStack.addLast( associationFetch );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract FetchStrategy determineFetchPlan(AssociationAttributeDefinition attributeDefinition);
|
||||
|
||||
protected int currentDepth() {
|
||||
return fetchOwnerStack.size();
|
||||
}
|
||||
|
||||
protected boolean isTooManyCollections() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract EntityReturn buildRootEntityReturn(EntityDefinition entityDefinition);
|
||||
|
||||
protected abstract CollectionReturn buildRootCollectionReturn(CollectionDefinition collectionDefinition);
|
||||
|
||||
protected abstract CollectionFetch buildCollectionFetch(
|
||||
FetchOwner fetchOwner,
|
||||
AssociationAttributeDefinition attributeDefinition,
|
||||
FetchStrategy fetchStrategy);
|
||||
|
||||
protected abstract EntityFetch buildEntityFetch(
|
||||
FetchOwner fetchOwner,
|
||||
AssociationAttributeDefinition attributeDefinition,
|
||||
FetchStrategy fetchStrategy);
|
||||
|
||||
protected abstract CompositeFetch buildCompositeFetch(FetchOwner fetchOwner, CompositeDefinition attributeDefinition);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
||||
/**
|
||||
* Base class for LoadPlan nodes to hold references to the session factory.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractPlanNode {
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
public AbstractPlanNode(SessionFactoryImplementor sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
protected SessionFactoryImplementor sessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.CollectionAliases;
|
||||
import org.hibernate.loader.EntityAliases;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.collection.QueryableCollection;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CollectionFetch extends AbstractFetch implements CollectionReference {
|
||||
private final CollectionAliases collectionAliases;
|
||||
private final EntityAliases elementEntityAliases;
|
||||
|
||||
private final CollectionPersister persister;
|
||||
|
||||
public CollectionFetch(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
String alias,
|
||||
LockMode lockMode,
|
||||
AbstractFetchOwner owner,
|
||||
FetchStrategy fetchStrategy,
|
||||
String ownerProperty,
|
||||
CollectionAliases collectionAliases,
|
||||
EntityAliases elementEntityAliases) {
|
||||
super( sessionFactory, alias, lockMode, owner, ownerProperty, fetchStrategy );
|
||||
this.collectionAliases = collectionAliases;
|
||||
this.elementEntityAliases = elementEntityAliases;
|
||||
|
||||
final String role = owner.retrieveFetchSourcePersister().getEntityName() + '.' + getOwnerPropertyName();
|
||||
this.persister = sessionFactory.getCollectionPersister( role );
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionAliases getCollectionAliases() {
|
||||
return collectionAliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityAliases getElementEntityAliases() {
|
||||
return elementEntityAliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionPersister getCollectionPersister() {
|
||||
return persister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister retrieveFetchSourcePersister() {
|
||||
return ( (QueryableCollection) getCollectionPersister() ).getElementPersister();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.loader.CollectionAliases;
|
||||
import org.hibernate.loader.EntityAliases;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
|
||||
/**
|
||||
* Represents a reference to an owned collection either as a return or as a fetch
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface CollectionReference {
|
||||
/**
|
||||
* Retrieve the alias associated with the persister (entity/collection).
|
||||
*
|
||||
* @return The alias
|
||||
*/
|
||||
public String getAlias();
|
||||
|
||||
/**
|
||||
* Retrieve the lock mode associated with this return.
|
||||
*
|
||||
* @return The lock mode.
|
||||
*/
|
||||
public LockMode getLockMode();
|
||||
|
||||
/**
|
||||
* Retrieves the CollectionPersister describing the collection associated with this Return.
|
||||
*
|
||||
* @return The CollectionPersister.
|
||||
*/
|
||||
public CollectionPersister getCollectionPersister();
|
||||
|
||||
/**
|
||||
* Returns the description of the aliases in the JDBC ResultSet that identify values "belonging" to the
|
||||
* this collection.
|
||||
*
|
||||
* @return The ResultSet alias descriptor for the collection
|
||||
*/
|
||||
public CollectionAliases getCollectionAliases();
|
||||
|
||||
/**
|
||||
* If the elements of this collection are entities, this methods returns the JDBC ResultSet alias descriptions
|
||||
* for that entity; {@code null} indicates a non-entity collection.
|
||||
*
|
||||
* @return The ResultSet alias descriptor for the collection's entity element, or {@code null}
|
||||
*/
|
||||
public EntityAliases getElementEntityAliases();
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.CollectionAliases;
|
||||
import org.hibernate.loader.EntityAliases;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.collection.QueryableCollection;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CollectionReturn extends AbstractFetchOwner implements Return, FetchOwner, CollectionReference {
|
||||
private final String ownerEntityName;
|
||||
private final String ownerProperty;
|
||||
private final CollectionAliases collectionAliases;
|
||||
private final EntityAliases elementEntityAliases;
|
||||
|
||||
private final CollectionPersister persister;
|
||||
|
||||
private final PropertyPath propertyPath = new PropertyPath(); // its a root
|
||||
|
||||
public CollectionReturn(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
String alias,
|
||||
LockMode lockMode,
|
||||
String ownerEntityName,
|
||||
String ownerProperty,
|
||||
CollectionAliases collectionAliases,
|
||||
EntityAliases elementEntityAliases) {
|
||||
super( sessionFactory, alias, lockMode );
|
||||
this.ownerEntityName = ownerEntityName;
|
||||
this.ownerProperty = ownerProperty;
|
||||
this.collectionAliases = collectionAliases;
|
||||
this.elementEntityAliases = elementEntityAliases;
|
||||
|
||||
final String role = ownerEntityName + '.' + ownerProperty;
|
||||
this.persister = sessionFactory.getCollectionPersister( role );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class owning the collection.
|
||||
*
|
||||
* @return The class owning the collection.
|
||||
*/
|
||||
public String getOwnerEntityName() {
|
||||
return ownerEntityName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the property representing the collection from the {@link #getOwnerEntityName}.
|
||||
*
|
||||
* @return The name of the property representing the collection on the owner class.
|
||||
*/
|
||||
public String getOwnerProperty() {
|
||||
return ownerProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionAliases getCollectionAliases() {
|
||||
return collectionAliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityAliases getElementEntityAliases() {
|
||||
return elementEntityAliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionPersister getCollectionPersister() {
|
||||
return persister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateFetchPlan(FetchStrategy fetchStrategy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister retrieveFetchSourcePersister() {
|
||||
return ( (QueryableCollection) persister ).getElementPersister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyPath getPropertyPath() {
|
||||
return propertyPath;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CompositeFetch extends AbstractFetch implements Fetch {
|
||||
public static final FetchStrategy FETCH_PLAN = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN );
|
||||
|
||||
public CompositeFetch(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
String alias,
|
||||
AbstractFetchOwner owner,
|
||||
String ownerProperty) {
|
||||
super( sessionFactory, alias, LockMode.NONE, owner, ownerProperty, FETCH_PLAN );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister retrieveFetchSourcePersister() {
|
||||
return getOwner().retrieveFetchSourcePersister();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.EntityAliases;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityFetch extends AbstractFetch implements EntityReference {
|
||||
private final String sqlTableAlias;
|
||||
private final EntityAliases entityAliases;
|
||||
|
||||
private final EntityPersister persister;
|
||||
|
||||
public EntityFetch(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
String alias,
|
||||
LockMode lockMode,
|
||||
AbstractFetchOwner owner,
|
||||
String ownerProperty,
|
||||
FetchStrategy fetchStrategy,
|
||||
String sqlTableAlias,
|
||||
EntityAliases entityAliases) {
|
||||
super( sessionFactory, alias, lockMode, owner, ownerProperty, fetchStrategy );
|
||||
this.sqlTableAlias = sqlTableAlias;
|
||||
this.entityAliases = entityAliases;
|
||||
|
||||
final EntityType type = (EntityType) owner.retrieveFetchSourcePersister().getPropertyType( ownerProperty );
|
||||
this.persister = sessionFactory.getEntityPersister( type.getAssociatedEntityName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister getEntityPersister() {
|
||||
return persister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityAliases getEntityAliases() {
|
||||
return entityAliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSqlTableAlias() {
|
||||
return sqlTableAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister retrieveFetchSourcePersister() {
|
||||
return persister;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.loader.EntityAliases;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* Represents a reference to an entity either as a return or as a fetch
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface EntityReference {
|
||||
/**
|
||||
* Retrieve the alias associated with the persister (entity/collection).
|
||||
*
|
||||
* @return The alias
|
||||
*/
|
||||
public String getAlias();
|
||||
|
||||
/**
|
||||
* Retrieve the lock mode associated with this return.
|
||||
*
|
||||
* @return The lock mode.
|
||||
*/
|
||||
public LockMode getLockMode();
|
||||
|
||||
/**
|
||||
* Retrieves the EntityPersister describing the entity associated with this Return.
|
||||
*
|
||||
* @return The EntityPersister.
|
||||
*/
|
||||
public EntityPersister getEntityPersister();
|
||||
|
||||
/**
|
||||
* Returns the description of the aliases in the JDBC ResultSet that identify values "belonging" to the this entity.
|
||||
*
|
||||
* @return The ResultSet alias descriptor.
|
||||
*/
|
||||
public EntityAliases getEntityAliases();
|
||||
|
||||
/**
|
||||
* Obtain the SQL table alias associated with this entity.
|
||||
*
|
||||
* TODO : eventually this needs to not be a String, but a representation like I did for the Antlr3 branch
|
||||
* (AliasRoot, I think it was called)
|
||||
*
|
||||
* @return The SQL table alias for this entity
|
||||
*/
|
||||
public String getSqlTableAlias();
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.EntityAliases;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityReturn extends AbstractFetchOwner implements Return, FetchOwner, EntityReference {
|
||||
private final EntityAliases entityAliases;
|
||||
private final String sqlTableAlias;
|
||||
|
||||
private final EntityPersister persister;
|
||||
|
||||
private final PropertyPath propertyPath = new PropertyPath(); // its a root
|
||||
|
||||
public EntityReturn(
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
String alias,
|
||||
LockMode lockMode,
|
||||
String entityName,
|
||||
String sqlTableAlias,
|
||||
EntityAliases entityAliases) {
|
||||
super( sessionFactory, alias, lockMode );
|
||||
this.entityAliases = entityAliases;
|
||||
this.sqlTableAlias = sqlTableAlias;
|
||||
|
||||
this.persister = sessionFactory.getEntityPersister( entityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return super.getAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockMode getLockMode() {
|
||||
return super.getLockMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister getEntityPersister() {
|
||||
return persister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityAliases getEntityAliases() {
|
||||
return entityAliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSqlTableAlias() {
|
||||
return sqlTableAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateFetchPlan(FetchStrategy fetchStrategy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister retrieveFetchSourcePersister() {
|
||||
return getEntityPersister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyPath getPropertyPath() {
|
||||
return propertyPath;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
|
||||
/**
|
||||
* Contract for associations that are being fetched.
|
||||
* <p/>
|
||||
* NOTE : can represent components/embeddables
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Fetch extends FetchOwner {
|
||||
/**
|
||||
* Obtain the owner of this fetch.
|
||||
*
|
||||
* @return The fetch owner.
|
||||
*/
|
||||
public FetchOwner getOwner();
|
||||
|
||||
/**
|
||||
* Obtain the name of the property, relative to the owner, being fetched.
|
||||
*
|
||||
* @return The fetched property name.
|
||||
*/
|
||||
public String getOwnerPropertyName();
|
||||
|
||||
public FetchStrategy getFetchStrategy();
|
||||
|
||||
/**
|
||||
* Get the property path to this fetch
|
||||
*
|
||||
* @return The property path
|
||||
*/
|
||||
public PropertyPath getPropertyPath();
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* Contract for owners of fetches. Any non-scalar return could be a fetch owner.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface FetchOwner {
|
||||
/**
|
||||
* Convenient constant for returning no fetches from {@link #getFetches()}
|
||||
*/
|
||||
public static final Fetch[] NO_FETCHES = new Fetch[0];
|
||||
|
||||
/**
|
||||
* Retrieve the fetches owned by this return.
|
||||
*
|
||||
* @return The owned fetches.
|
||||
*/
|
||||
public Fetch[] getFetches();
|
||||
|
||||
/**
|
||||
* Is the asserted plan valid from this owner to a fetch?
|
||||
*
|
||||
* @param fetchStrategy The pla to validate
|
||||
*/
|
||||
public void validateFetchPlan(FetchStrategy fetchStrategy);
|
||||
|
||||
/**
|
||||
* Retrieve the EntityPersister that is the base for any property references in the fetches it owns.
|
||||
*
|
||||
* @return The EntityPersister, for property name resolution.
|
||||
*/
|
||||
public EntityPersister retrieveFetchSourcePersister();
|
||||
|
||||
/**
|
||||
* Get the property path to this fetch owner
|
||||
*
|
||||
* @return The property path
|
||||
*/
|
||||
public PropertyPath getPropertyPath();
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Describes a plan for performing a load of results.
|
||||
*
|
||||
* Generally speaking there are 3 forms of load plans:<ul>
|
||||
* <li>
|
||||
* An entity load plan for handling get/load handling. This form will typically have a single
|
||||
* return (of type {@link EntityReturn}) defined by {@link #getReturns()}, possibly defining fetches.
|
||||
* </li>
|
||||
* <li>
|
||||
* A collection initializer, used to load the contents of a collection. This form will typically have a
|
||||
* single return (of type {@link CollectionReturn} defined by {@link #getReturns()}, possibly defining fetches
|
||||
* </li>
|
||||
* <li>
|
||||
* A query load plan which can contain multiple returns of mixed type (though implementing {@link Return}).
|
||||
* Again, may possibly define fetches.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface LoadPlan {
|
||||
/**
|
||||
* Convenient form of checking {@link #getReturns()} for scalar root returns.
|
||||
*
|
||||
* @return {@code true} if {@link #getReturns()} contained any scalar returns; {@code false} otherwise.
|
||||
*/
|
||||
public boolean hasAnyScalarReturns();
|
||||
|
||||
public List<Return> getReturns();
|
||||
|
||||
// todo : would also like to see "call back" style access for handling "subsequent actions" such as:
|
||||
// 1) follow-on locking
|
||||
// 2) join fetch conversions to subselect fetches
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor;
|
||||
|
||||
/**
|
||||
* Coordinates building of a {@link LoadPlan} between the {@link org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor} and
|
||||
* {@link LoadPlanBuilderStrategy}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LoadPlanBuilder {
|
||||
/**
|
||||
* Coordinates building a LoadPlan that defines just a single root entity return (may have fetches).
|
||||
* <p/>
|
||||
* Typically this includes building load plans for entity loading or cascade loading.
|
||||
*
|
||||
* @param strategy The strategy defining the load plan shaping
|
||||
* @param persister The persister for the entity forming the root of the load plan.
|
||||
*
|
||||
* @return The built load plan.
|
||||
*/
|
||||
public static LoadPlan buildRootEntityLoadPlan(LoadPlanBuilderStrategy strategy, EntityPersister persister) {
|
||||
MetadataDrivenModelGraphVisitor.visitEntity( strategy, persister );
|
||||
return strategy.buildLoadPlan();
|
||||
}
|
||||
|
||||
/**
|
||||
* Coordinates building a LoadPlan that defines just a single root collection return (may have fetches).
|
||||
*
|
||||
* @param strategy The strategy defining the load plan shaping
|
||||
* @param persister The persister for the collection forming the root of the load plan.
|
||||
*
|
||||
* @return The built load plan.
|
||||
*/
|
||||
public static LoadPlan buildRootCollectionLoadPlan(LoadPlanBuilderStrategy strategy, CollectionPersister persister) {
|
||||
MetadataDrivenModelGraphVisitor.visitCollection( strategy, persister );
|
||||
return strategy.buildLoadPlan();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.persister.walking.spi.AssociationVisitationStrategy;
|
||||
|
||||
/**
|
||||
* Specialized {@link org.hibernate.persister.walking.spi.AssociationVisitationStrategy} implementation for building {@link LoadPlan} instances.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface LoadPlanBuilderStrategy extends AssociationVisitationStrategy {
|
||||
/**
|
||||
* After visitation is done, build the load plan.
|
||||
*
|
||||
* @return The load plan
|
||||
*/
|
||||
public LoadPlan buildLoadPlan();
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
/**
|
||||
* Represents a return value in the query results. Not the same as a result (column) in the JDBC ResultSet!
|
||||
* <p/>
|
||||
* This is merely a unifying contract; it defines no behavior.
|
||||
* <p/>
|
||||
* Return is distinctly different from a {@link Fetch}.
|
||||
*
|
||||
* @see ScalarReturn
|
||||
* @see EntityReturn
|
||||
* @see CollectionReturn
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Return {
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ReturnVisitationStrategy {
|
||||
/**
|
||||
* Notification we are preparing to start visitation.
|
||||
*/
|
||||
public void start();
|
||||
|
||||
/**
|
||||
* Notification we are finished visitation.
|
||||
*/
|
||||
public void finish();
|
||||
|
||||
/**
|
||||
* Notification that a new root return branch is being started. Will be followed by calls to one of the following
|
||||
* based on the type of return:<ul>
|
||||
* <li>{@link #handleScalarReturn}</li>
|
||||
* <li>{@link #handleEntityReturn}</li>
|
||||
* <li>{@link #handleCollectionReturn}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param rootReturn The root return at the root of the branch.
|
||||
*/
|
||||
public void startingRootReturn(Return rootReturn);
|
||||
|
||||
/**
|
||||
* Notification that we are finishing up processing a root return branch
|
||||
*
|
||||
* @param rootReturn The RootReturn we are finishing up processing.
|
||||
*/
|
||||
public void finishingRootReturn(Return rootReturn);
|
||||
|
||||
/**
|
||||
* Notification that a scalar return is being processed. Will be surrounded by calls to {@link #startingRootReturn}
|
||||
* and {@link #finishingRootReturn}
|
||||
*
|
||||
* @param scalarReturn The scalar return
|
||||
*/
|
||||
public void handleScalarReturn(ScalarReturn scalarReturn);
|
||||
|
||||
/**
|
||||
* Notification that a root entity return is being processed. Will be surrounded by calls to
|
||||
* {@link #startingRootReturn} and {@link #finishingRootReturn}
|
||||
*
|
||||
* @param rootEntityReturn The root entity return
|
||||
*/
|
||||
public void handleEntityReturn(EntityReturn rootEntityReturn);
|
||||
|
||||
/**
|
||||
* Notification that a root collection return is being processed. Will be surrounded by calls to
|
||||
* {@link #startingRootReturn} and {@link #finishingRootReturn}
|
||||
*
|
||||
* @param rootCollectionReturn The root collection return
|
||||
*/
|
||||
public void handleCollectionReturn(CollectionReturn rootCollectionReturn);
|
||||
|
||||
/**
|
||||
* Notification that we are about to start processing the fetches for the given fetch owner.
|
||||
*
|
||||
* @param fetchOwner The fetch owner.
|
||||
*/
|
||||
public void startingFetches(FetchOwner fetchOwner);
|
||||
|
||||
/**
|
||||
* Notification that we are finishing up processing the fetches for the given fetch owner.
|
||||
*
|
||||
* @param fetchOwner The fetch owner.
|
||||
*/
|
||||
public void finishingFetches(FetchOwner fetchOwner);
|
||||
|
||||
/**
|
||||
* Notification we are starting the processing of an entity fetch
|
||||
*
|
||||
* @param entityFetch The entity fetch
|
||||
*/
|
||||
public void startingEntityFetch(EntityFetch entityFetch);
|
||||
|
||||
/**
|
||||
* Notification that we are finishing up the processing of an entity fetch
|
||||
*
|
||||
* @param entityFetch The entity fetch
|
||||
*/
|
||||
public void finishingEntityFetch(EntityFetch entityFetch);
|
||||
|
||||
/**
|
||||
* Notification we are starting the processing of a collection fetch
|
||||
*
|
||||
* @param collectionFetch The collection fetch
|
||||
*/
|
||||
public void startingCollectionFetch(CollectionFetch collectionFetch);
|
||||
|
||||
/**
|
||||
* Notification that we are finishing up the processing of a collection fetch
|
||||
*
|
||||
* @param collectionFetch The collection fetch
|
||||
*/
|
||||
public void finishingCollectionFetch(CollectionFetch collectionFetch);
|
||||
|
||||
/**
|
||||
* Notification we are starting the processing of a component fetch
|
||||
*
|
||||
* @param fetch The composite fetch
|
||||
*/
|
||||
public void startingCompositeFetch(CompositeFetch fetch);
|
||||
|
||||
/**
|
||||
* Notification that we are finishing up the processing of a composite fetch
|
||||
*
|
||||
* @param fetch The composite fetch
|
||||
*/
|
||||
public void finishingCompositeFetch(CompositeFetch fetch);
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
/**
|
||||
* Visitor for processing {@link Return} graphs
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ReturnVisitor {
|
||||
public static void visit(Return[] rootReturns, ReturnVisitationStrategy strategy) {
|
||||
new ReturnVisitor( strategy ).visitReturns( rootReturns );
|
||||
}
|
||||
|
||||
private final ReturnVisitationStrategy strategy;
|
||||
|
||||
public ReturnVisitor(ReturnVisitationStrategy strategy) {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
private void visitReturns(Return[] rootReturns) {
|
||||
strategy.start();
|
||||
|
||||
for ( Return rootReturn : rootReturns ) {
|
||||
visitRootReturn( rootReturn );
|
||||
}
|
||||
|
||||
strategy.finish();
|
||||
}
|
||||
|
||||
private void visitRootReturn(Return rootReturn) {
|
||||
strategy.startingRootReturn( rootReturn );
|
||||
|
||||
if ( org.hibernate.loader.plan.spi.ScalarReturn.class.isInstance( rootReturn ) ) {
|
||||
strategy.handleScalarReturn( (ScalarReturn) rootReturn );
|
||||
}
|
||||
else {
|
||||
visitNonScalarRootReturn( rootReturn );
|
||||
}
|
||||
|
||||
strategy.finishingRootReturn( rootReturn );
|
||||
}
|
||||
|
||||
private void visitNonScalarRootReturn(Return rootReturn) {
|
||||
if ( EntityReturn.class.isInstance( rootReturn ) ) {
|
||||
strategy.handleEntityReturn( (EntityReturn) rootReturn );
|
||||
visitFetches( (EntityReturn) rootReturn );
|
||||
}
|
||||
else if ( CollectionReturn.class.isInstance( rootReturn ) ) {
|
||||
strategy.handleCollectionReturn( (CollectionReturn) rootReturn );
|
||||
visitFetches( (CollectionReturn) rootReturn );
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"Unexpected return type encountered; expecting a non-scalar root return, but found " +
|
||||
rootReturn.getClass().getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void visitFetches(FetchOwner fetchOwner) {
|
||||
strategy.startingFetches( fetchOwner );
|
||||
|
||||
for ( Fetch fetch : fetchOwner.getFetches() ) {
|
||||
visitFetch( fetch );
|
||||
}
|
||||
|
||||
strategy.finishingFetches( fetchOwner );
|
||||
}
|
||||
|
||||
private void visitFetch(Fetch fetch) {
|
||||
if ( EntityFetch.class.isInstance( fetch ) ) {
|
||||
strategy.startingEntityFetch( (EntityFetch) fetch );
|
||||
visitFetches( fetch );
|
||||
strategy.finishingEntityFetch( (EntityFetch) fetch );
|
||||
}
|
||||
else if ( CollectionFetch.class.isInstance( fetch ) ) {
|
||||
strategy.startingCollectionFetch( (CollectionFetch) fetch );
|
||||
visitFetches( fetch );
|
||||
strategy.finishingCollectionFetch( (CollectionFetch) fetch );
|
||||
}
|
||||
else if ( CompositeFetch.class.isInstance( fetch ) ) {
|
||||
strategy.startingCompositeFetch( (CompositeFetch) fetch );
|
||||
visitFetches( fetch );
|
||||
strategy.finishingCompositeFetch( (CompositeFetch) fetch );
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"Unexpected return type encountered; expecting a fetch return, but found " +
|
||||
fetch.getClass().getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Represent a simple scalar return within a query result. Generally this would be values of basic (String, Integer,
|
||||
* etc) or composite types.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ScalarReturn extends AbstractPlanNode implements Return {
|
||||
private final Type type;
|
||||
private final String columnAlias;
|
||||
|
||||
public ScalarReturn(SessionFactoryImplementor factory, Type type, String columnAlias) {
|
||||
super( factory );
|
||||
this.type = type;
|
||||
this.columnAlias = columnAlias;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getColumnAlias() {
|
||||
return columnAlias;
|
||||
}
|
||||
}
|
|
@ -79,6 +79,11 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.Loadable;
|
||||
import org.hibernate.persister.entity.PropertyMapping;
|
||||
import org.hibernate.persister.entity.Queryable;
|
||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
||||
import org.hibernate.persister.walking.spi.CompositeDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.sql.Alias;
|
||||
import org.hibernate.sql.SelectFragment;
|
||||
|
@ -90,6 +95,7 @@ import org.hibernate.sql.ordering.antlr.FormulaReference;
|
|||
import org.hibernate.sql.ordering.antlr.OrderByAliasResolver;
|
||||
import org.hibernate.sql.ordering.antlr.OrderByTranslation;
|
||||
import org.hibernate.sql.ordering.antlr.SqlValueReference;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
@ -1934,4 +1940,79 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
public abstract FilterAliasGenerator getFilterAliasGenerator(final String rootAlias);
|
||||
|
||||
|
||||
// ColectionDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public CollectionPersister getCollectionPersister() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionIndexDefinition getIndexDefinition() {
|
||||
if ( ! hasIndex() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CollectionIndexDefinition() {
|
||||
@Override
|
||||
public CollectionDefinition getCollectionDefinition() {
|
||||
return AbstractCollectionPersister.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return getIndexType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDefinition toEntityDefinition() {
|
||||
if ( getType().isComponentType() ) {
|
||||
throw new IllegalStateException( "Cannot treat composite collection index type as entity" );
|
||||
}
|
||||
return (EntityPersister) ( (AssociationType) getIndexType() ).getAssociatedJoinable( getFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompositeDefinition toCompositeDefinition() {
|
||||
if ( ! getType().isComponentType() ) {
|
||||
throw new IllegalStateException( "Cannot treat entity collection index type as composite" );
|
||||
}
|
||||
// todo : implement
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionElementDefinition getElementDefinition() {
|
||||
return new CollectionElementDefinition() {
|
||||
@Override
|
||||
public CollectionDefinition getCollectionDefinition() {
|
||||
return AbstractCollectionPersister.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return getElementType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDefinition toEntityDefinition() {
|
||||
if ( getType().isComponentType() ) {
|
||||
throw new IllegalStateException( "Cannot treat composite collection element type as entity" );
|
||||
}
|
||||
return getElementPersister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompositeDefinition toCompositeDefinition() {
|
||||
if ( ! getType().isComponentType() ) {
|
||||
throw new IllegalStateException( "Cannot treat entity collection element type as composite" );
|
||||
}
|
||||
// todo : implement
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.hibernate.engine.spi.SessionImplementor;
|
|||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.metadata.CollectionMetadata;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
|
@ -60,7 +61,7 @@ import org.hibernate.type.Type;
|
|||
* @see org.hibernate.collection.spi.PersistentCollection
|
||||
* @author Gavin King
|
||||
*/
|
||||
public interface CollectionPersister {
|
||||
public interface CollectionPersister extends CollectionDefinition {
|
||||
/**
|
||||
* Initialize the given collection with the given key
|
||||
*/
|
||||
|
|
|
@ -59,6 +59,7 @@ import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl;
|
|||
import org.hibernate.cache.spi.entry.StandardCacheEntryImpl;
|
||||
import org.hibernate.cache.spi.entry.StructuredCacheEntry;
|
||||
import org.hibernate.cache.spi.entry.UnstructuredCacheEntry;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.dialect.lock.LockingStrategy;
|
||||
import org.hibernate.engine.OptimisticLockStyle;
|
||||
import org.hibernate.engine.internal.StatefulPersistenceContext;
|
||||
|
@ -91,7 +92,6 @@ import org.hibernate.internal.util.collections.ArrayHelper;
|
|||
import org.hibernate.jdbc.Expectation;
|
||||
import org.hibernate.jdbc.Expectations;
|
||||
import org.hibernate.jdbc.TooManyRowsAffectedException;
|
||||
import org.hibernate.loader.entity.BatchingEntityLoader;
|
||||
import org.hibernate.loader.entity.BatchingEntityLoaderBuilder;
|
||||
import org.hibernate.loader.entity.CascadeEntityLoader;
|
||||
import org.hibernate.loader.entity.EntityLoader;
|
||||
|
@ -109,6 +109,7 @@ import org.hibernate.metamodel.binding.SimpleValueBinding;
|
|||
import org.hibernate.metamodel.binding.SingularAttributeBinding;
|
||||
import org.hibernate.metamodel.relational.DerivedValue;
|
||||
import org.hibernate.metamodel.relational.Value;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.property.BackrefPropertyAccessor;
|
||||
import org.hibernate.sql.Alias;
|
||||
|
@ -504,7 +505,7 @@ public abstract class AbstractEntityPersister
|
|||
this.naturalIdRegionAccessStrategy = naturalIdRegionAccessStrategy;
|
||||
isLazyPropertiesCacheable = persistentClass.isLazyPropertiesCacheable();
|
||||
|
||||
this.entityMetamodel = new EntityMetamodel( persistentClass, factory );
|
||||
this.entityMetamodel = new EntityMetamodel( persistentClass, this, factory );
|
||||
this.entityTuplizer = this.entityMetamodel.getTuplizer();
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -834,7 +835,7 @@ public abstract class AbstractEntityPersister
|
|||
entityBinding.getHierarchyDetails().getCaching() == null ?
|
||||
false :
|
||||
entityBinding.getHierarchyDetails().getCaching().isCacheLazyProperties();
|
||||
this.entityMetamodel = new EntityMetamodel( entityBinding, factory );
|
||||
this.entityMetamodel = new EntityMetamodel( entityBinding, this, factory );
|
||||
this.entityTuplizer = this.entityMetamodel.getTuplizer();
|
||||
int batch = entityBinding.getBatchSize();
|
||||
if ( batch == -1 ) {
|
||||
|
@ -3816,10 +3817,11 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
public void postInstantiate() throws MappingException {
|
||||
generateEntityDefinition();
|
||||
|
||||
createLoaders();
|
||||
createUniqueKeyLoaders();
|
||||
createQueryLoader();
|
||||
|
||||
}
|
||||
|
||||
//needed by subclasses to override the createLoader strategy
|
||||
|
@ -5070,4 +5072,110 @@ public abstract class AbstractEntityPersister
|
|||
throw new HibernateException( "Illegal attempt to build cache entry for non-cached entity" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// EntityDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
private Iterable<AttributeDefinition> embeddedCompositeIdentifierAttributes;
|
||||
private Iterable<AttributeDefinition> attributeDefinitions;
|
||||
|
||||
protected void generateEntityDefinition() {
|
||||
collectEmbeddedCompositeIdentifierAttributeDefinitions();
|
||||
collectAttributeDefinitions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister getEntityPersister() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AttributeDefinition> getEmbeddedCompositeIdentifierAttributes() {
|
||||
return embeddedCompositeIdentifierAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AttributeDefinition> getAttributes() {
|
||||
return attributeDefinitions;
|
||||
}
|
||||
|
||||
private synchronized void collectEmbeddedCompositeIdentifierAttributeDefinitions() {
|
||||
final Type idType = getIdentifierType();
|
||||
if ( !idType.isComponentType() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final CompositeType cidType = (CompositeType) idType;
|
||||
if ( !cidType.isEmbedded() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// we have an embedded composite identifier. Most likely we need to process the composite
|
||||
// properties separately, although there is an edge case where the identifier is really
|
||||
// a simple identifier (single value) wrapped in a JPA @IdClass or even in the case of a
|
||||
// a simple identifier (single value) wrapped in a Hibernate composite type.
|
||||
//
|
||||
// We really do not have a built-in method to determine that. However, generally the
|
||||
// persister would report that there is single, physical identifier property which is
|
||||
// explicitly at odds with the notion of "embedded composite". So we use that for now
|
||||
if ( getEntityMetamodel().getIdentifierProperty().isEmbedded() ) {
|
||||
this.embeddedCompositeIdentifierAttributes = new Iterable<AttributeDefinition>() {
|
||||
@Override
|
||||
public Iterator<AttributeDefinition> iterator() {
|
||||
return new Iterator<AttributeDefinition>() {
|
||||
private final int numberOfAttributes = countSubclassProperties();
|
||||
private int currentAttributeNumber = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return currentAttributeNumber < numberOfAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeDefinition next() {
|
||||
// todo : implement
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException( "Remove operation not supported here" );
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void collectAttributeDefinitions() {
|
||||
// todo : leverage the attribute definitions housed on EntityMetamodel
|
||||
// for that to work, we'd have to be able to walk our super entity persister(s)
|
||||
attributeDefinitions = new Iterable<AttributeDefinition>() {
|
||||
@Override
|
||||
public Iterator<AttributeDefinition> iterator() {
|
||||
return new Iterator<AttributeDefinition>() {
|
||||
// private final int numberOfAttributes = countSubclassProperties();
|
||||
private final int numberOfAttributes = entityMetamodel.getPropertySpan();
|
||||
private int currentAttributeNumber = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return currentAttributeNumber < numberOfAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeDefinition next() {
|
||||
final int attributeNumber = currentAttributeNumber;
|
||||
currentAttributeNumber++;
|
||||
return entityMetamodel.getProperties()[ attributeNumber ];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException( "Remove operation not supported here" );
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,22 +44,25 @@ import org.hibernate.engine.spi.ValueInclusion;
|
|||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.internal.FilterAliasGenerator;
|
||||
import org.hibernate.metadata.ClassMetadata;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.VersionType;
|
||||
|
||||
/**
|
||||
* Implementors define mapping and persistence logic for a particular
|
||||
* strategy of entity mapping. An instance of entity persisters corresponds
|
||||
* to a given mapped entity.
|
||||
* Contract describing mapping information and persistence logic for a particular strategy of entity mapping. A given
|
||||
* persister instance corresponds to a given mapped entity class.
|
||||
* <p/>
|
||||
* Implementors must be threadsafe (preferrably immutable) and must provide a constructor
|
||||
* matching the signature of: {@link org.hibernate.mapping.PersistentClass}, {@link org.hibernate.engine.spi.SessionFactoryImplementor}
|
||||
* Implementations must be thread-safe (preferably immutable).
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
* @see org.hibernate.persister.spi.PersisterFactory
|
||||
* @see org.hibernate.persister.spi.PersisterClassResolver
|
||||
*/
|
||||
public interface EntityPersister extends OptimisticCacheSource {
|
||||
public interface EntityPersister extends OptimisticCacheSource, EntityDefinition {
|
||||
|
||||
/**
|
||||
* The property name of the "special" identifier property in HQL
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.internal;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.profile.Fetch;
|
||||
import org.hibernate.engine.profile.FetchProfile;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
import org.hibernate.persister.collection.AbstractCollectionPersister;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||
import org.hibernate.type.AssociationType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Helper {
|
||||
/**
|
||||
* Determine the fetch-style (if one) explicitly set for this association via fetch profiles.
|
||||
* <p/>
|
||||
* Note that currently fetch profiles only allow specifying join fetching, so this method currently
|
||||
* returns either (a) FetchStyle.JOIN or (b) null
|
||||
*
|
||||
* @param loadQueryInfluencers
|
||||
* @param persister
|
||||
* @param path
|
||||
* @param propertyNumber
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static FetchStyle determineFetchStyleByProfile(
|
||||
LoadQueryInfluencers loadQueryInfluencers,
|
||||
EntityPersister persister,
|
||||
PropertyPath path,
|
||||
int propertyNumber) {
|
||||
if ( !loadQueryInfluencers.hasEnabledFetchProfiles() ) {
|
||||
// perf optimization
|
||||
return null;
|
||||
}
|
||||
|
||||
// ugh, this stuff has to be made easier...
|
||||
final String fullPath = path.getFullPath();
|
||||
final String rootPropertyName = ( (OuterJoinLoadable) persister ).getSubclassPropertyName( propertyNumber );
|
||||
int pos = fullPath.lastIndexOf( rootPropertyName );
|
||||
final String relativePropertyPath = pos >= 0
|
||||
? fullPath.substring( pos )
|
||||
: rootPropertyName;
|
||||
final String fetchRole = persister.getEntityName() + "." + relativePropertyPath;
|
||||
|
||||
Iterator profiles = loadQueryInfluencers.getEnabledFetchProfileNames().iterator();
|
||||
while ( profiles.hasNext() ) {
|
||||
final String profileName = ( String ) profiles.next();
|
||||
final FetchProfile profile = loadQueryInfluencers.getSessionFactory().getFetchProfile( profileName );
|
||||
final Fetch fetch = profile.getFetchByRole( fetchRole );
|
||||
if ( fetch != null && Fetch.Style.JOIN == fetch.getStyle() ) {
|
||||
return FetchStyle.JOIN;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mappingFetchMode The mapping defined fetch mode
|
||||
* @param type The association type
|
||||
* @param sessionFactory The session factory
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static FetchStyle determineFetchStyleByMetadata(
|
||||
FetchMode mappingFetchMode,
|
||||
AssociationType type,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
if ( !type.isEntityType() && !type.isCollectionType() ) {
|
||||
return FetchStyle.SELECT;
|
||||
}
|
||||
|
||||
if ( mappingFetchMode == FetchMode.JOIN ) {
|
||||
return FetchStyle.JOIN;
|
||||
}
|
||||
|
||||
if ( type.isEntityType() ) {
|
||||
EntityPersister persister = (EntityPersister) type.getAssociatedJoinable( sessionFactory );
|
||||
if ( persister.isBatchLoadable() ) {
|
||||
return FetchStyle.BATCH;
|
||||
}
|
||||
}
|
||||
else {
|
||||
CollectionPersister persister = (CollectionPersister) type.getAssociatedJoinable( sessionFactory );
|
||||
if ( persister instanceof AbstractCollectionPersister
|
||||
&& ( (AbstractCollectionPersister) persister ).isSubselectLoadable() ) {
|
||||
return FetchStyle.SUBSELECT;
|
||||
}
|
||||
else if ( persister.getBatchSize() > 0 ) {
|
||||
return FetchStyle.BATCH;
|
||||
}
|
||||
}
|
||||
|
||||
return FetchStyle.SELECT;
|
||||
}
|
||||
|
||||
public static FetchTiming determineFetchTiming(
|
||||
FetchStyle style,
|
||||
AssociationType type,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
switch ( style ) {
|
||||
case JOIN: {
|
||||
return FetchTiming.IMMEDIATE;
|
||||
}
|
||||
case BATCH:
|
||||
case SUBSELECT: {
|
||||
return FetchTiming.DELAYED;
|
||||
}
|
||||
default: {
|
||||
// SELECT case, can be either
|
||||
return isSubsequentSelectDelayed( type, sessionFactory )
|
||||
? FetchTiming.DELAYED
|
||||
: FetchTiming.IMMEDIATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSubsequentSelectDelayed(AssociationType type, SessionFactoryImplementor sessionFactory) {
|
||||
if ( type.isEntityType() ) {
|
||||
return ( (EntityPersister) type.getAssociatedJoinable( sessionFactory ) ).hasProxy();
|
||||
}
|
||||
else {
|
||||
final CollectionPersister cp = ( (CollectionPersister) type.getAssociatedJoinable( sessionFactory ) );
|
||||
return cp.isLazy() || cp.isExtraLazy();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface AssociationAttributeDefinition extends AttributeDefinition {
|
||||
public AssociationKey getAssociationKey();
|
||||
|
||||
public boolean isCollection();
|
||||
|
||||
public EntityDefinition toEntityDefinition();
|
||||
|
||||
public CollectionDefinition toCollectionDefinition();
|
||||
|
||||
public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath);
|
||||
|
||||
public CascadeStyle determineCascadeStyle();
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Used to uniquely identify a foreign key, so that we don't join it more than once creating circularities.
|
||||
* <p/>
|
||||
* bit of a misnomer to call this an association attribute. But this follows the legacy use of AssociationKey
|
||||
* from old JoinWalkers to denote circular join detection
|
||||
*/
|
||||
public class AssociationKey {
|
||||
private final String table;
|
||||
private final String[] columns;
|
||||
|
||||
public AssociationKey(String table, String[] columns) {
|
||||
this.table = table;
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
AssociationKey that = (AssociationKey) other;
|
||||
return that.table.equals(table) && Arrays.equals( columns, that.columns );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return table.hashCode(); //TODO: inefficient
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface AssociationVisitationStrategy {
|
||||
/**
|
||||
* Notification we are preparing to start visitation.
|
||||
*/
|
||||
public void start();
|
||||
|
||||
/**
|
||||
* Notification we are finished visitation.
|
||||
*/
|
||||
public void finish();
|
||||
|
||||
public void startingEntity(EntityDefinition entityDefinition);
|
||||
public void finishingEntity(EntityDefinition entityDefinition);
|
||||
|
||||
public void startingCollection(CollectionDefinition collectionDefinition);
|
||||
public void finishingCollection(CollectionDefinition collectionDefinition);
|
||||
|
||||
public void startingComposite(CompositeDefinition compositeDefinition);
|
||||
public void finishingComposite(CompositeDefinition compositeDefinition);
|
||||
|
||||
public boolean startingAttribute(AttributeDefinition attributeDefinition);
|
||||
public void finishingAttribute(AttributeDefinition attributeDefinition);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface AttributeDefinition {
|
||||
public String getName();
|
||||
public Type getType();
|
||||
public AttributeSource getSource();
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface AttributeSource {
|
||||
public Iterable<AttributeDefinition> getAttributes();
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.type.CollectionType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface CollectionDefinition {
|
||||
public CollectionPersister getCollectionPersister();
|
||||
public CollectionType getCollectionType();
|
||||
|
||||
public CollectionIndexDefinition getIndexDefinition();
|
||||
public CollectionElementDefinition getElementDefinition();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface CollectionElementDefinition {
|
||||
public CollectionDefinition getCollectionDefinition();
|
||||
|
||||
public Type getType();
|
||||
|
||||
public EntityDefinition toEntityDefinition();
|
||||
|
||||
public CompositeDefinition toCompositeDefinition();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface CollectionIndexDefinition {
|
||||
public CollectionDefinition getCollectionDefinition();
|
||||
|
||||
public Type getType();
|
||||
|
||||
public EntityDefinition toEntityDefinition();
|
||||
|
||||
public CompositeDefinition toCompositeDefinition();
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface CompositeDefinition extends AttributeDefinition, AttributeSource {
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* Defines the contract for walking the attributes defined by an entity
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface EntityDefinition extends AttributeSource {
|
||||
public EntityPersister getEntityPersister();
|
||||
public Iterable<AttributeDefinition> getEmbeddedCompositeIdentifierAttributes();
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Provides model graph visitation based on the defined metadata (as opposed to based on the incoming graph
|
||||
* as we see in cascade processing). In layman terms, we are walking the graph of the users model as defined by
|
||||
* mapped associations.
|
||||
* <p/>
|
||||
* Re-implementation of the legacy {@link org.hibernate.loader.JoinWalker} contract to leverage load plans.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class MetadataDrivenModelGraphVisitor {
|
||||
private static final Logger log = Logger.getLogger( MetadataDrivenModelGraphVisitor.class );
|
||||
|
||||
public static void visitEntity(AssociationVisitationStrategy strategy, EntityPersister persister) {
|
||||
strategy.start();
|
||||
try {
|
||||
new MetadataDrivenModelGraphVisitor( strategy, persister.getFactory() )
|
||||
.visitEntityDefinition( persister );
|
||||
}
|
||||
finally {
|
||||
strategy.finish();
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitCollection(AssociationVisitationStrategy strategy, CollectionPersister persister) {
|
||||
strategy.start();
|
||||
try {
|
||||
new MetadataDrivenModelGraphVisitor( strategy, persister.getFactory() )
|
||||
.visitCollectionDefinition( persister );
|
||||
}
|
||||
finally {
|
||||
strategy.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private final AssociationVisitationStrategy strategy;
|
||||
private final SessionFactoryImplementor factory;
|
||||
|
||||
// todo : add a getDepth() method to PropertyPath
|
||||
private PropertyPath currentPropertyPath = new PropertyPath();
|
||||
|
||||
public MetadataDrivenModelGraphVisitor(AssociationVisitationStrategy strategy, SessionFactoryImplementor factory) {
|
||||
this.strategy = strategy;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
private void visitEntityDefinition(EntityDefinition entityDefinition) {
|
||||
strategy.startingEntity( entityDefinition );
|
||||
try {
|
||||
visitAttributes( entityDefinition );
|
||||
optionallyVisitEmbeddedCompositeIdentifier( entityDefinition );
|
||||
}
|
||||
finally {
|
||||
strategy.finishingEntity( entityDefinition );
|
||||
}
|
||||
}
|
||||
|
||||
private void optionallyVisitEmbeddedCompositeIdentifier(EntityDefinition entityDefinition) {
|
||||
// if the entity has a composite identifier, see if we need to handle its sub-properties separately
|
||||
final Iterable<AttributeDefinition> embeddedCompositeIdentifierAttributes =
|
||||
entityDefinition.getEmbeddedCompositeIdentifierAttributes();
|
||||
if ( embeddedCompositeIdentifierAttributes == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( AttributeDefinition attributeDefinition : embeddedCompositeIdentifierAttributes ) {
|
||||
visitAttributeDefinition( attributeDefinition );
|
||||
}
|
||||
}
|
||||
|
||||
private void visitAttributes(AttributeSource attributeSource) {
|
||||
for ( AttributeDefinition attributeDefinition : attributeSource.getAttributes() ) {
|
||||
visitAttributeDefinition( attributeDefinition );
|
||||
}
|
||||
}
|
||||
|
||||
private void visitAttributeDefinition(AttributeDefinition attributeDefinition) {
|
||||
final PropertyPath subPath = currentPropertyPath.append( attributeDefinition.getName() );
|
||||
log.debug( "Visiting attribute path : " + subPath.getFullPath() );
|
||||
|
||||
final boolean continueWalk = strategy.startingAttribute( attributeDefinition );
|
||||
if ( continueWalk ) {
|
||||
final PropertyPath old = currentPropertyPath;
|
||||
currentPropertyPath = subPath;
|
||||
try {
|
||||
if ( attributeDefinition.getType().isAssociationType() ) {
|
||||
visitAssociation( (AssociationAttributeDefinition) attributeDefinition );
|
||||
}
|
||||
else if ( attributeDefinition.getType().isComponentType() ) {
|
||||
visitCompositeDefinition( (CompositeDefinition) attributeDefinition );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
currentPropertyPath = old;
|
||||
}
|
||||
}
|
||||
strategy.finishingAttribute( attributeDefinition );
|
||||
}
|
||||
|
||||
private void visitAssociation(AssociationAttributeDefinition attribute) {
|
||||
// todo : do "too deep" checks; but see note about adding depth to PropertyPath
|
||||
|
||||
if ( isDuplicateAssociation( attribute.getAssociationKey() ) ) {
|
||||
log.debug( "Property path deemed to be circular : " + currentPropertyPath.getFullPath() );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( attribute.isCollection() ) {
|
||||
visitCollectionDefinition( attribute.toCollectionDefinition() );
|
||||
}
|
||||
else {
|
||||
visitEntityDefinition( attribute.toEntityDefinition() );
|
||||
}
|
||||
}
|
||||
|
||||
private void visitCompositeDefinition(CompositeDefinition compositeDefinition) {
|
||||
strategy.startingComposite( compositeDefinition );
|
||||
try {
|
||||
visitAttributes( compositeDefinition );
|
||||
}
|
||||
finally {
|
||||
strategy.finishingComposite( compositeDefinition );
|
||||
}
|
||||
}
|
||||
|
||||
private void visitCollectionDefinition(CollectionDefinition collectionDefinition) {
|
||||
strategy.startingCollection( collectionDefinition );
|
||||
|
||||
try {
|
||||
visitCollectionIndex( collectionDefinition.getIndexDefinition() );
|
||||
|
||||
final CollectionElementDefinition elementDefinition = collectionDefinition.getElementDefinition();
|
||||
if ( elementDefinition.getType().isComponentType() ) {
|
||||
visitCompositeDefinition( elementDefinition.toCompositeDefinition() );
|
||||
}
|
||||
else {
|
||||
visitEntityDefinition( elementDefinition.toEntityDefinition() );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
strategy.finishingCollection( collectionDefinition );
|
||||
}
|
||||
}
|
||||
|
||||
private void visitCollectionIndex(CollectionIndexDefinition collectionIndexDefinition) {
|
||||
if ( collectionIndexDefinition == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug( "Visiting collection index : " + currentPropertyPath.getFullPath() );
|
||||
currentPropertyPath = currentPropertyPath.append( "<key>" );
|
||||
try {
|
||||
final Type collectionIndexType = collectionIndexDefinition.getType();
|
||||
if ( collectionIndexType.isComponentType() ) {
|
||||
visitCompositeDefinition( collectionIndexDefinition.toCompositeDefinition() );
|
||||
}
|
||||
else if ( collectionIndexType.isAssociationType() ) {
|
||||
visitEntityDefinition( collectionIndexDefinition.toEntityDefinition() );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
currentPropertyPath = currentPropertyPath.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final Set<AssociationKey> visitedAssociationKeys = new HashSet<AssociationKey>();
|
||||
|
||||
protected boolean isDuplicateAssociation(AssociationKey associationKey) {
|
||||
return !visitedAssociationKeys.add( associationKey );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package org.hibernate.persister.walking.spi;
|
||||
|
||||
/**
|
||||
* Package for "walking" associations through metadata definition. Ultimately want {@link org.hibernate.persister.walking.spi.AttributeDefinition} and
|
||||
* {@link AttributeSource} etc to become part of the persister model.
|
||||
*/
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple;
|
||||
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractAttribute implements Attribute, Property {
|
||||
private final String attributeName;
|
||||
private final Type attributeType;
|
||||
|
||||
protected AbstractAttribute(String attributeName, Type attributeType) {
|
||||
this.attributeName = attributeName;
|
||||
this.attributeType = attributeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String getNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return attributeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return attributeType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.walking.spi.AttributeSource;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractNonIdentifierAttribute extends AbstractAttribute implements NonIdentifierAttribute {
|
||||
private final AttributeSource source;
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
private final int attributeNumber;
|
||||
|
||||
private final BaselineAttributeInformation attributeInformation;
|
||||
|
||||
protected AbstractNonIdentifierAttribute(
|
||||
AttributeSource source,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
Type attributeType,
|
||||
BaselineAttributeInformation attributeInformation) {
|
||||
super( attributeName, attributeType );
|
||||
this.source = source;
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.attributeNumber = attributeNumber;
|
||||
this.attributeInformation = attributeInformation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeSource getSource() {
|
||||
return source();
|
||||
}
|
||||
|
||||
protected AttributeSource source() {
|
||||
return source;
|
||||
}
|
||||
|
||||
protected SessionFactoryImplementor sessionFactory() {
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
protected int attributeNumber() {
|
||||
return attributeNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLazy() {
|
||||
return attributeInformation.isLazy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsertable() {
|
||||
return attributeInformation.isInsertable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdateable() {
|
||||
return attributeInformation.isUpdateable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsertGenerated() {
|
||||
return attributeInformation.isInsertGenerated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdateGenerated() {
|
||||
return attributeInformation.isUpdateGenerated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return attributeInformation.isNullable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirtyCheckable() {
|
||||
return attributeInformation.isDirtyCheckable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirtyCheckable(boolean hasUninitializedProperties) {
|
||||
return isDirtyCheckable() && ( !hasUninitializedProperties || !isLazy() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVersionable() {
|
||||
return attributeInformation.isVersionable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CascadeStyle getCascadeStyle() {
|
||||
return attributeInformation.getCascadeStyle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchMode getFetchMode() {
|
||||
return attributeInformation.getFetchMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Attribute[non-identifier]( " + getName() + ")";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple;
|
||||
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Contract for attributes
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Attribute {
|
||||
public String getName();
|
||||
public Type getType();
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package org.hibernate.tuple;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BaselineAttributeInformation {
|
||||
private final boolean lazy;
|
||||
private final boolean insertable;
|
||||
private final boolean updateable;
|
||||
private final boolean insertGenerated;
|
||||
private final boolean updateGenerated;
|
||||
private final boolean nullable;
|
||||
private final boolean dirtyCheckable;
|
||||
private final boolean versionable;
|
||||
private final CascadeStyle cascadeStyle;
|
||||
private final FetchMode fetchMode;
|
||||
private boolean checkable;
|
||||
|
||||
public BaselineAttributeInformation(
|
||||
boolean lazy,
|
||||
boolean insertable,
|
||||
boolean updateable,
|
||||
boolean insertGenerated,
|
||||
boolean updateGenerated,
|
||||
boolean nullable,
|
||||
boolean dirtyCheckable,
|
||||
boolean versionable,
|
||||
CascadeStyle cascadeStyle,
|
||||
FetchMode fetchMode) {
|
||||
this.lazy = lazy;
|
||||
this.insertable = insertable;
|
||||
this.updateable = updateable;
|
||||
this.insertGenerated = insertGenerated;
|
||||
this.updateGenerated = updateGenerated;
|
||||
this.nullable = nullable;
|
||||
this.dirtyCheckable = dirtyCheckable;
|
||||
this.versionable = versionable;
|
||||
this.cascadeStyle = cascadeStyle;
|
||||
this.fetchMode = fetchMode;
|
||||
}
|
||||
|
||||
public boolean isLazy() {
|
||||
return lazy;
|
||||
}
|
||||
|
||||
public boolean isInsertable() {
|
||||
return insertable;
|
||||
}
|
||||
|
||||
public boolean isUpdateable() {
|
||||
return updateable;
|
||||
}
|
||||
|
||||
public boolean isInsertGenerated() {
|
||||
return insertGenerated;
|
||||
}
|
||||
|
||||
public boolean isUpdateGenerated() {
|
||||
return updateGenerated;
|
||||
}
|
||||
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
public boolean isDirtyCheckable() {
|
||||
return dirtyCheckable;
|
||||
}
|
||||
|
||||
public boolean isVersionable() {
|
||||
return versionable;
|
||||
}
|
||||
|
||||
public CascadeStyle getCascadeStyle() {
|
||||
return cascadeStyle;
|
||||
}
|
||||
|
||||
public FetchMode getFetchMode() {
|
||||
return fetchMode;
|
||||
}
|
||||
|
||||
public boolean isCheckable() {
|
||||
return checkable;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private boolean lazy;
|
||||
private boolean insertable;
|
||||
private boolean updateable;
|
||||
private boolean insertGenerated;
|
||||
private boolean updateGenerated;
|
||||
private boolean nullable;
|
||||
private boolean dirtyCheckable;
|
||||
private boolean versionable;
|
||||
private CascadeStyle cascadeStyle;
|
||||
private FetchMode fetchMode;
|
||||
|
||||
public Builder setLazy(boolean lazy) {
|
||||
this.lazy = lazy;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setInsertable(boolean insertable) {
|
||||
this.insertable = insertable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setUpdateable(boolean updateable) {
|
||||
this.updateable = updateable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setInsertGenerated(boolean insertGenerated) {
|
||||
this.insertGenerated = insertGenerated;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setUpdateGenerated(boolean updateGenerated) {
|
||||
this.updateGenerated = updateGenerated;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setNullable(boolean nullable) {
|
||||
this.nullable = nullable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDirtyCheckable(boolean dirtyCheckable) {
|
||||
this.dirtyCheckable = dirtyCheckable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setVersionable(boolean versionable) {
|
||||
this.versionable = versionable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCascadeStyle(CascadeStyle cascadeStyle) {
|
||||
this.cascadeStyle = cascadeStyle;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setFetchMode(FetchMode fetchMode) {
|
||||
this.fetchMode = fetchMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BaselineAttributeInformation createInformation() {
|
||||
return new BaselineAttributeInformation(
|
||||
lazy,
|
||||
insertable,
|
||||
updateable,
|
||||
insertGenerated,
|
||||
updateGenerated,
|
||||
nullable,
|
||||
dirtyCheckable,
|
||||
versionable,
|
||||
cascadeStyle,
|
||||
fetchMode
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.hibernate.tuple;
|
||||
|
||||
import org.hibernate.engine.spi.IdentifierValue;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface IdentifierAttribute extends Attribute, Property {
|
||||
boolean isVirtual();
|
||||
|
||||
boolean isEmbedded();
|
||||
|
||||
IdentifierValue getUnsavedValue();
|
||||
|
||||
IdentifierGenerator getIdentifierGenerator();
|
||||
|
||||
boolean isIdentifierAssignedByInsert();
|
||||
|
||||
boolean hasIdentifierMapper();
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,9 +20,9 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.tuple;
|
||||
|
||||
import org.hibernate.engine.spi.IdentifierValue;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.PostInsertIdentifierGenerator;
|
||||
|
@ -34,7 +34,7 @@ import org.hibernate.type.Type;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class IdentifierProperty extends Property {
|
||||
public class IdentifierProperty extends AbstractAttribute implements IdentifierAttribute {
|
||||
|
||||
private boolean virtual;
|
||||
private boolean embedded;
|
||||
|
@ -63,7 +63,7 @@ public class IdentifierProperty extends Property {
|
|||
boolean embedded,
|
||||
IdentifierValue unsavedValue,
|
||||
IdentifierGenerator identifierGenerator) {
|
||||
super(name, node, type);
|
||||
super( name, type );
|
||||
this.virtual = false;
|
||||
this.embedded = embedded;
|
||||
this.hasIdentifierMapper = false;
|
||||
|
@ -87,7 +87,7 @@ public class IdentifierProperty extends Property {
|
|||
boolean hasIdentifierMapper,
|
||||
IdentifierValue unsavedValue,
|
||||
IdentifierGenerator identifierGenerator) {
|
||||
super(null, null, type);
|
||||
super( null, type );
|
||||
this.virtual = true;
|
||||
this.embedded = embedded;
|
||||
this.hasIdentifierMapper = hasIdentifierMapper;
|
||||
|
@ -96,27 +96,38 @@ public class IdentifierProperty extends Property {
|
|||
this.identifierAssignedByInsert = identifierGenerator instanceof PostInsertIdentifierGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVirtual() {
|
||||
return virtual;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmbedded() {
|
||||
return embedded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierValue getUnsavedValue() {
|
||||
return unsavedValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierGenerator getIdentifierGenerator() {
|
||||
return identifierGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdentifierAssignedByInsert() {
|
||||
return identifierAssignedByInsert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIdentifierMapper() {
|
||||
return hasIdentifierMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IdentifierAttribute(" + getName() + ")";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface NonIdentifierAttribute extends Attribute, AttributeDefinition {
|
||||
public boolean isLazy();
|
||||
|
||||
public boolean isInsertable();
|
||||
|
||||
public boolean isUpdateable();
|
||||
|
||||
public boolean isInsertGenerated();
|
||||
|
||||
public boolean isUpdateGenerated();
|
||||
|
||||
public boolean isNullable();
|
||||
|
||||
public boolean isDirtyCheckable(boolean hasUninitializedProperties);
|
||||
|
||||
public boolean isDirtyCheckable();
|
||||
|
||||
public boolean isVersionable();
|
||||
|
||||
public CascadeStyle getCascadeStyle();
|
||||
|
||||
public FetchMode getFetchMode();
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,52 +20,16 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.tuple;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Defines the basic contract of a Property within the runtime metamodel.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class Property implements Serializable {
|
||||
private String name;
|
||||
private String node;
|
||||
private Type type;
|
||||
|
||||
/**
|
||||
* Constructor for Property instances.
|
||||
*
|
||||
* @param name The name by which the property can be referenced within
|
||||
* its owner.
|
||||
* @param node The node name to use for XML-based representation of this
|
||||
* property.
|
||||
* @param type The Hibernate Type of this property.
|
||||
*/
|
||||
protected Property(String name, String node, Type type) {
|
||||
this.name = name;
|
||||
this.node = node;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Property(" + name + ':' + type.getName() + ')';
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public interface Property extends Attribute {
|
||||
@Deprecated
|
||||
public String getNode();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,17 +20,20 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.tuple;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.engine.internal.UnsavedValueFactory;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.CascadeStyles;
|
||||
import org.hibernate.engine.spi.IdentifierValue;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.VersionValue;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
|
@ -45,10 +48,16 @@ import org.hibernate.metamodel.binding.BasicAttributeBinding;
|
|||
import org.hibernate.metamodel.binding.EntityBinding;
|
||||
import org.hibernate.metamodel.binding.SimpleValueBinding;
|
||||
import org.hibernate.metamodel.binding.SingularAttributeBinding;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.property.Getter;
|
||||
import org.hibernate.property.PropertyAccessor;
|
||||
import org.hibernate.property.PropertyAccessorFactory;
|
||||
import org.hibernate.tuple.entity.EntityBasedAssociationAttribute;
|
||||
import org.hibernate.tuple.entity.EntityBasedBasicAttribute;
|
||||
import org.hibernate.tuple.entity.EntityBasedCompositeAttribute;
|
||||
import org.hibernate.tuple.entity.VersionProperty;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.VersionType;
|
||||
|
||||
|
@ -59,16 +68,16 @@ import org.hibernate.type.VersionType;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PropertyFactory {
|
||||
|
||||
/**
|
||||
* Generates an IdentifierProperty representation of the for a given entity mapping.
|
||||
* Generates the attribute representation of the identifier for a given entity mapping.
|
||||
*
|
||||
* @param mappedEntity The mapping definition of the entity.
|
||||
* @param generator The identifier value generator to use for this identifier.
|
||||
* @return The appropriate IdentifierProperty definition.
|
||||
*/
|
||||
public static IdentifierProperty buildIdentifierProperty(PersistentClass mappedEntity, IdentifierGenerator generator) {
|
||||
|
||||
public static IdentifierProperty buildIdentifierAttribute(
|
||||
PersistentClass mappedEntity,
|
||||
IdentifierGenerator generator) {
|
||||
String mappedUnsavedValue = mappedEntity.getIdentifier().getNullValue();
|
||||
Type type = mappedEntity.getIdentifier().getType();
|
||||
Property property = mappedEntity.getIdentifierProperty();
|
||||
|
@ -109,7 +118,9 @@ public class PropertyFactory {
|
|||
* @param generator The identifier value generator to use for this identifier.
|
||||
* @return The appropriate IdentifierProperty definition.
|
||||
*/
|
||||
public static IdentifierProperty buildIdentifierProperty(EntityBinding mappedEntity, IdentifierGenerator generator) {
|
||||
public static IdentifierProperty buildIdentifierProperty(
|
||||
EntityBinding mappedEntity,
|
||||
IdentifierGenerator generator) {
|
||||
|
||||
final BasicAttributeBinding property = mappedEntity.getHierarchyDetails().getEntityIdentifier().getValueBinding();
|
||||
|
||||
|
@ -157,7 +168,12 @@ public class PropertyFactory {
|
|||
* @param lazyAvailable Is property lazy loading currently available.
|
||||
* @return The appropriate VersionProperty definition.
|
||||
*/
|
||||
public static VersionProperty buildVersionProperty(Property property, boolean lazyAvailable) {
|
||||
public static VersionProperty buildVersionProperty(
|
||||
EntityPersister persister,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
Property property,
|
||||
boolean lazyAvailable) {
|
||||
String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue();
|
||||
|
||||
VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
|
||||
|
@ -165,23 +181,27 @@ public class PropertyFactory {
|
|||
getGetter( property ),
|
||||
(VersionType) property.getType(),
|
||||
getConstructor( property.getPersistentClass() )
|
||||
);
|
||||
);
|
||||
|
||||
boolean lazy = lazyAvailable && property.isLazy();
|
||||
|
||||
return new VersionProperty(
|
||||
persister,
|
||||
sessionFactory,
|
||||
attributeNumber,
|
||||
property.getName(),
|
||||
property.getNodeName(),
|
||||
property.getValue().getType(),
|
||||
lazy,
|
||||
property.isInsertable(),
|
||||
property.isUpdateable(),
|
||||
property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
property.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
property.isOptional(),
|
||||
property.isUpdateable() && !lazy,
|
||||
property.isOptimisticLocked(),
|
||||
property.getCascadeStyle(),
|
||||
new BaselineAttributeInformation.Builder()
|
||||
.setLazy( lazy )
|
||||
.setInsertable( property.isInsertable() )
|
||||
.setUpdateable( property.isUpdateable() )
|
||||
.setInsertGenerated( property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS )
|
||||
.setUpdateGenerated( property.getGeneration() == PropertyGeneration.ALWAYS )
|
||||
.setNullable( property.isOptional() )
|
||||
.setDirtyCheckable( property.isUpdateable() && !lazy )
|
||||
.setVersionable( property.isOptimisticLocked() )
|
||||
.setCascadeStyle( property.getCascadeStyle() )
|
||||
.createInformation(),
|
||||
unsavedValue
|
||||
);
|
||||
}
|
||||
|
@ -194,52 +214,38 @@ public class PropertyFactory {
|
|||
* @param lazyAvailable Is property lazy loading currently available.
|
||||
* @return The appropriate VersionProperty definition.
|
||||
*/
|
||||
public static VersionProperty buildVersionProperty(BasicAttributeBinding property, boolean lazyAvailable) {
|
||||
String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue();
|
||||
public static VersionProperty buildVersionProperty(
|
||||
EntityPersister persister,
|
||||
BasicAttributeBinding property,
|
||||
boolean lazyAvailable) {
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
|
||||
VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
|
||||
mappedUnsavedValue,
|
||||
getGetter( property ),
|
||||
(VersionType) property.getHibernateTypeDescriptor().getResolvedTypeMapping(),
|
||||
getConstructor( (EntityBinding) property.getContainer() )
|
||||
);
|
||||
|
||||
boolean lazy = lazyAvailable && property.isLazy();
|
||||
|
||||
final CascadeStyle cascadeStyle = property.isAssociation()
|
||||
? ( (AssociationAttributeBinding) property ).getCascadeStyle()
|
||||
: CascadeStyles.NONE;
|
||||
|
||||
return new VersionProperty(
|
||||
property.getAttribute().getName(),
|
||||
null,
|
||||
property.getHibernateTypeDescriptor().getResolvedTypeMapping(),
|
||||
lazy,
|
||||
true, // insertable
|
||||
true, // updatable
|
||||
property.getGeneration() == PropertyGeneration.INSERT
|
||||
|| property.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
property.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
property.isNullable(),
|
||||
!lazy,
|
||||
property.isIncludedInOptimisticLocking(),
|
||||
cascadeStyle,
|
||||
unsavedValue
|
||||
);
|
||||
public static enum NonIdentifierAttributeNature {
|
||||
BASIC,
|
||||
COMPOSITE,
|
||||
ANY,
|
||||
ENTITY,
|
||||
COLLECTION
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a "standard" (i.e., non-identifier and non-version) based on the given
|
||||
* mapped property.
|
||||
* Generate a non-identifier (and non-version) attribute based on the given mapped property from the given entity
|
||||
*
|
||||
* @param property The mapped property.
|
||||
* @param lazyAvailable Is property lazy loading currently available.
|
||||
* @return The appropriate StandardProperty definition.
|
||||
* @return The appropriate NonIdentifierProperty definition.
|
||||
*/
|
||||
public static StandardProperty buildStandardProperty(Property property, boolean lazyAvailable) {
|
||||
|
||||
public static NonIdentifierAttribute buildEntityBasedAttribute(
|
||||
EntityPersister persister,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
Property property,
|
||||
boolean lazyAvailable) {
|
||||
final Type type = property.getValue().getType();
|
||||
|
||||
|
||||
final NonIdentifierAttributeNature nature = decode( type );
|
||||
|
||||
// we need to dirty check collections, since they can cause an owner
|
||||
// version number increment
|
||||
|
||||
|
@ -250,30 +256,147 @@ public class PropertyFactory {
|
|||
boolean alwaysDirtyCheck = type.isAssociationType() &&
|
||||
( (AssociationType) type ).isAlwaysDirtyChecked();
|
||||
|
||||
switch ( nature ) {
|
||||
case BASIC: {
|
||||
return new EntityBasedBasicAttribute(
|
||||
persister,
|
||||
sessionFactory,
|
||||
attributeNumber,
|
||||
property.getName(),
|
||||
type,
|
||||
new BaselineAttributeInformation.Builder()
|
||||
.setLazy( lazyAvailable && property.isLazy() )
|
||||
.setInsertable( property.isInsertable() )
|
||||
.setUpdateable( property.isUpdateable() )
|
||||
.setInsertGenerated(
|
||||
property.getGeneration() == PropertyGeneration.INSERT
|
||||
|| property.getGeneration() == PropertyGeneration.ALWAYS
|
||||
)
|
||||
.setUpdateGenerated( property.getGeneration() == PropertyGeneration.ALWAYS )
|
||||
.setNullable( property.isOptional() )
|
||||
.setDirtyCheckable( alwaysDirtyCheck || property.isUpdateable() )
|
||||
.setVersionable( property.isOptimisticLocked() )
|
||||
.setCascadeStyle( property.getCascadeStyle() )
|
||||
.setFetchMode( property.getValue().getFetchMode() )
|
||||
.createInformation()
|
||||
);
|
||||
}
|
||||
case COMPOSITE: {
|
||||
return new EntityBasedCompositeAttribute(
|
||||
persister,
|
||||
sessionFactory,
|
||||
attributeNumber,
|
||||
property.getName(),
|
||||
(CompositeType) type,
|
||||
new BaselineAttributeInformation.Builder()
|
||||
.setLazy( lazyAvailable && property.isLazy() )
|
||||
.setInsertable( property.isInsertable() )
|
||||
.setUpdateable( property.isUpdateable() )
|
||||
.setInsertGenerated(
|
||||
property.getGeneration() == PropertyGeneration.INSERT
|
||||
|| property.getGeneration() == PropertyGeneration.ALWAYS
|
||||
)
|
||||
.setUpdateGenerated( property.getGeneration() == PropertyGeneration.ALWAYS )
|
||||
.setNullable( property.isOptional() )
|
||||
.setDirtyCheckable( alwaysDirtyCheck || property.isUpdateable() )
|
||||
.setVersionable( property.isOptimisticLocked() )
|
||||
.setCascadeStyle( property.getCascadeStyle() )
|
||||
.setFetchMode( property.getValue().getFetchMode() )
|
||||
.createInformation()
|
||||
);
|
||||
}
|
||||
case ENTITY:
|
||||
case ANY:
|
||||
case COLLECTION: {
|
||||
return new EntityBasedAssociationAttribute(
|
||||
persister,
|
||||
sessionFactory,
|
||||
attributeNumber,
|
||||
property.getName(),
|
||||
(AssociationType) type,
|
||||
new BaselineAttributeInformation.Builder()
|
||||
.setLazy( lazyAvailable && property.isLazy() )
|
||||
.setInsertable( property.isInsertable() )
|
||||
.setUpdateable( property.isUpdateable() )
|
||||
.setInsertGenerated(
|
||||
property.getGeneration() == PropertyGeneration.INSERT
|
||||
|| property.getGeneration() == PropertyGeneration.ALWAYS
|
||||
)
|
||||
.setUpdateGenerated( property.getGeneration() == PropertyGeneration.ALWAYS )
|
||||
.setNullable( property.isOptional() )
|
||||
.setDirtyCheckable( alwaysDirtyCheck || property.isUpdateable() )
|
||||
.setVersionable( property.isOptimisticLocked() )
|
||||
.setCascadeStyle( property.getCascadeStyle() )
|
||||
.setFetchMode( property.getValue().getFetchMode() )
|
||||
.createInformation()
|
||||
);
|
||||
}
|
||||
default: {
|
||||
throw new HibernateException( "Internal error" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static NonIdentifierAttributeNature decode(Type type) {
|
||||
if ( type.isAssociationType() ) {
|
||||
AssociationType associationType = (AssociationType) type;
|
||||
|
||||
if ( type.isComponentType() ) {
|
||||
// an any type is both an association and a composite...
|
||||
return NonIdentifierAttributeNature.ANY;
|
||||
}
|
||||
|
||||
return type.isCollectionType()
|
||||
? NonIdentifierAttributeNature.COLLECTION
|
||||
: NonIdentifierAttributeNature.ENTITY;
|
||||
}
|
||||
else {
|
||||
if ( type.isComponentType() ) {
|
||||
return NonIdentifierAttributeNature.COMPOSITE;
|
||||
}
|
||||
|
||||
return NonIdentifierAttributeNature.BASIC;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static StandardProperty buildStandardProperty(Property property, boolean lazyAvailable) {
|
||||
final Type type = property.getValue().getType();
|
||||
|
||||
// we need to dirty check collections, since they can cause an owner
|
||||
// version number increment
|
||||
|
||||
// we need to dirty check many-to-ones with not-found="ignore" in order
|
||||
// to update the cache (not the database), since in this case a null
|
||||
// entity reference can lose information
|
||||
|
||||
boolean alwaysDirtyCheck = type.isAssociationType() &&
|
||||
( (AssociationType) type ).isAlwaysDirtyChecked();
|
||||
|
||||
return new StandardProperty(
|
||||
property.getName(),
|
||||
property.getNodeName(),
|
||||
type,
|
||||
lazyAvailable && property.isLazy(),
|
||||
property.isInsertable(),
|
||||
property.isUpdateable(),
|
||||
property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
property.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
property.isOptional(),
|
||||
alwaysDirtyCheck || property.isUpdateable(),
|
||||
property.isOptimisticLocked(),
|
||||
property.getCascadeStyle(),
|
||||
property.getValue().getFetchMode()
|
||||
);
|
||||
property.getValue().getFetchMode()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a "standard" (i.e., non-identifier and non-version) based on the given
|
||||
* mapped property.
|
||||
*
|
||||
* @param property The mapped property.
|
||||
* @param lazyAvailable Is property lazy loading currently available.
|
||||
* @return The appropriate StandardProperty definition.
|
||||
* @return The appropriate NonIdentifierProperty definition.
|
||||
*/
|
||||
public static StandardProperty buildStandardProperty(AttributeBinding property, boolean lazyAvailable) {
|
||||
|
||||
|
@ -299,7 +422,6 @@ public class PropertyFactory {
|
|||
|
||||
return new StandardProperty(
|
||||
singularAttributeBinding.getAttribute().getName(),
|
||||
null,
|
||||
type,
|
||||
lazyAvailable && singularAttributeBinding.isLazy(),
|
||||
true, // insertable
|
||||
|
@ -325,7 +447,6 @@ public class PropertyFactory {
|
|||
|
||||
return new StandardProperty(
|
||||
pluralAttributeBinding.getAttribute().getName(),
|
||||
null,
|
||||
type,
|
||||
lazyAvailable && pluralAttributeBinding.isLazy(),
|
||||
// TODO: fix this when HHH-6356 is fixed; for now assume AbstractPluralAttributeBinding is updatable and insertable
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,118 +20,69 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.tuple;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Represents a basic property within the Hibernate runtime-metamodel.
|
||||
* Represents a non-identifier property within the Hibernate runtime-metamodel.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardProperty extends Property {
|
||||
@Deprecated
|
||||
public class StandardProperty extends AbstractNonIdentifierAttribute implements NonIdentifierAttribute {
|
||||
|
||||
private final boolean lazy;
|
||||
private final boolean insertable;
|
||||
private final boolean updateable;
|
||||
private final boolean insertGenerated;
|
||||
private final boolean updateGenerated;
|
||||
private final boolean nullable;
|
||||
private final boolean dirtyCheckable;
|
||||
private final boolean versionable;
|
||||
private final CascadeStyle cascadeStyle;
|
||||
private final FetchMode fetchMode;
|
||||
|
||||
/**
|
||||
* Constructs StandardProperty instances.
|
||||
*
|
||||
* @param name The name by which the property can be referenced within
|
||||
* its owner.
|
||||
* @param node The node name to use for XML-based representation of this
|
||||
* property.
|
||||
* @param type The Hibernate Type of this property.
|
||||
* @param lazy Should this property be handled lazily?
|
||||
* @param insertable Is this property an insertable value?
|
||||
* @param updateable Is this property an updateable value?
|
||||
* @param insertGenerated Is this property generated in the database on insert?
|
||||
* @param updateGenerated Is this property generated in the database on update?
|
||||
* @param nullable Is this property a nullable value?
|
||||
* @param checkable Is this property a checkable value?
|
||||
* @param versionable Is this property a versionable value?
|
||||
* @param cascadeStyle The cascade style for this property's value.
|
||||
* @param fetchMode Any fetch mode defined for this property
|
||||
*/
|
||||
public StandardProperty(
|
||||
String name,
|
||||
String node,
|
||||
Type type,
|
||||
boolean lazy,
|
||||
boolean insertable,
|
||||
boolean updateable,
|
||||
boolean insertGenerated,
|
||||
boolean updateGenerated,
|
||||
boolean nullable,
|
||||
boolean checkable,
|
||||
boolean versionable,
|
||||
CascadeStyle cascadeStyle,
|
||||
FetchMode fetchMode) {
|
||||
super(name, node, type);
|
||||
this.lazy = lazy;
|
||||
this.insertable = insertable;
|
||||
this.updateable = updateable;
|
||||
this.insertGenerated = insertGenerated;
|
||||
this.updateGenerated = updateGenerated;
|
||||
this.nullable = nullable;
|
||||
this.dirtyCheckable = checkable;
|
||||
this.versionable = versionable;
|
||||
this.cascadeStyle = cascadeStyle;
|
||||
this.fetchMode = fetchMode;
|
||||
}
|
||||
|
||||
public boolean isLazy() {
|
||||
return lazy;
|
||||
}
|
||||
|
||||
public boolean isInsertable() {
|
||||
return insertable;
|
||||
}
|
||||
|
||||
public boolean isUpdateable() {
|
||||
return updateable;
|
||||
}
|
||||
|
||||
public boolean isInsertGenerated() {
|
||||
return insertGenerated;
|
||||
}
|
||||
|
||||
public boolean isUpdateGenerated() {
|
||||
return updateGenerated;
|
||||
}
|
||||
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
public boolean isDirtyCheckable(boolean hasUninitializedProperties) {
|
||||
return isDirtyCheckable() && ( !hasUninitializedProperties || !isLazy() );
|
||||
}
|
||||
|
||||
public boolean isDirtyCheckable() {
|
||||
return dirtyCheckable;
|
||||
}
|
||||
|
||||
public boolean isVersionable() {
|
||||
return versionable;
|
||||
}
|
||||
|
||||
public CascadeStyle getCascadeStyle() {
|
||||
return cascadeStyle;
|
||||
}
|
||||
|
||||
public FetchMode getFetchMode() {
|
||||
return fetchMode;
|
||||
/**
|
||||
* Constructs NonIdentifierProperty instances.
|
||||
*
|
||||
* @param name The name by which the property can be referenced within
|
||||
* its owner.
|
||||
* @param type The Hibernate Type of this property.
|
||||
* @param lazy Should this property be handled lazily?
|
||||
* @param insertable Is this property an insertable value?
|
||||
* @param updateable Is this property an updateable value?
|
||||
* @param insertGenerated Is this property generated in the database on insert?
|
||||
* @param updateGenerated Is this property generated in the database on update?
|
||||
* @param nullable Is this property a nullable value?
|
||||
* @param checkable Is this property a checkable value?
|
||||
* @param versionable Is this property a versionable value?
|
||||
* @param cascadeStyle The cascade style for this property's value.
|
||||
* @param fetchMode Any fetch mode defined for this property
|
||||
*/
|
||||
public StandardProperty(
|
||||
String name,
|
||||
Type type,
|
||||
boolean lazy,
|
||||
boolean insertable,
|
||||
boolean updateable,
|
||||
boolean insertGenerated,
|
||||
boolean updateGenerated,
|
||||
boolean nullable,
|
||||
boolean checkable,
|
||||
boolean versionable,
|
||||
CascadeStyle cascadeStyle,
|
||||
FetchMode fetchMode) {
|
||||
super(
|
||||
null,
|
||||
null,
|
||||
-1,
|
||||
name,
|
||||
type,
|
||||
new BaselineAttributeInformation.Builder()
|
||||
.setLazy( lazy )
|
||||
.setInsertable( insertable )
|
||||
.setUpdateable( updateable )
|
||||
.setInsertGenerated( insertGenerated )
|
||||
.setUpdateGenerated( updateGenerated )
|
||||
.setNullable( nullable )
|
||||
.setDirtyCheckable( checkable )
|
||||
.setVersionable( versionable )
|
||||
.setCascadeStyle( cascadeStyle )
|
||||
.setFetchMode( fetchMode )
|
||||
.createInformation()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.tuple;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.VersionValue;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Represents a version property within the Hibernate runtime-metamodel.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class VersionProperty extends StandardProperty {
|
||||
|
||||
private final VersionValue unsavedValue;
|
||||
|
||||
/**
|
||||
* Constructs VersionProperty instances.
|
||||
*
|
||||
* @param name The name by which the property can be referenced within
|
||||
* its owner.
|
||||
* @param node The node name to use for XML-based representation of this
|
||||
* property.
|
||||
* @param type The Hibernate Type of this property.
|
||||
* @param lazy Should this property be handled lazily?
|
||||
* @param insertable Is this property an insertable value?
|
||||
* @param updateable Is this property an updateable value?
|
||||
* @param insertGenerated Is this property generated in the database on insert?
|
||||
* @param updateGenerated Is this property generated in the database on update?
|
||||
* @param nullable Is this property a nullable value?
|
||||
* @param checkable Is this property a checkable value?
|
||||
* @param versionable Is this property a versionable value?
|
||||
* @param cascadeStyle The cascade style for this property's value.
|
||||
* @param unsavedValue The value which, if found as the value of
|
||||
* this (i.e., the version) property, represents new (i.e., un-saved)
|
||||
* instances of the owning entity.
|
||||
*/
|
||||
public VersionProperty(
|
||||
String name,
|
||||
String node,
|
||||
Type type,
|
||||
boolean lazy,
|
||||
boolean insertable,
|
||||
boolean updateable,
|
||||
boolean insertGenerated,
|
||||
boolean updateGenerated,
|
||||
boolean nullable,
|
||||
boolean checkable,
|
||||
boolean versionable,
|
||||
CascadeStyle cascadeStyle,
|
||||
VersionValue unsavedValue) {
|
||||
super( name, node, type, lazy, insertable, updateable, insertGenerated, updateGenerated, nullable, checkable, versionable, cascadeStyle, null );
|
||||
this.unsavedValue = unsavedValue;
|
||||
}
|
||||
|
||||
public VersionValue getUnsavedValue() {
|
||||
return unsavedValue;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple.component;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.tuple.AbstractNonIdentifierAttribute;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.tuple.NonIdentifierAttribute;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractCompositeBasedAttribute
|
||||
extends AbstractNonIdentifierAttribute
|
||||
implements NonIdentifierAttribute {
|
||||
|
||||
private final int ownerAttributeNumber;
|
||||
|
||||
public AbstractCompositeBasedAttribute(
|
||||
AbstractCompositeDefinition source,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
Type attributeType,
|
||||
BaselineAttributeInformation baselineInfo,
|
||||
int ownerAttributeNumber) {
|
||||
super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo );
|
||||
this.ownerAttributeNumber = ownerAttributeNumber;
|
||||
}
|
||||
|
||||
protected int ownerAttributeNumber() {
|
||||
return ownerAttributeNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractCompositeDefinition getSource() {
|
||||
return (AbstractCompositeDefinition) super.getSource();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple.component;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Joinable;
|
||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||
import org.hibernate.persister.walking.spi.AssociationKey;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.AttributeSource;
|
||||
import org.hibernate.persister.walking.spi.CompositeDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.tuple.AbstractNonIdentifierAttribute;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.ForeignKeyDirection;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import static org.hibernate.engine.internal.JoinHelper.getLHSColumnNames;
|
||||
import static org.hibernate.engine.internal.JoinHelper.getLHSTableName;
|
||||
import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractCompositeDefinition extends AbstractNonIdentifierAttribute implements CompositeDefinition {
|
||||
protected AbstractCompositeDefinition(
|
||||
AttributeSource source,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
CompositeType attributeType,
|
||||
BaselineAttributeInformation baselineInfo) {
|
||||
super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo );
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompositeType getType() {
|
||||
return (CompositeType) super.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AttributeDefinition> getAttributes() {
|
||||
return new Iterable<AttributeDefinition>() {
|
||||
@Override
|
||||
public Iterator<AttributeDefinition> iterator() {
|
||||
return new Iterator<AttributeDefinition>() {
|
||||
private final int numberOfAttributes = getType().getSubtypes().length;
|
||||
private int currentAttributeNumber = 0;
|
||||
private int currentColumnPosition = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return currentAttributeNumber < numberOfAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeDefinition next() {
|
||||
final int attributeNumber = currentAttributeNumber;
|
||||
currentAttributeNumber++;
|
||||
|
||||
final String name = getType().getPropertyNames()[attributeNumber];
|
||||
final Type type = getType().getSubtypes()[attributeNumber];
|
||||
|
||||
int columnPosition = currentColumnPosition;
|
||||
currentColumnPosition += type.getColumnSpan( sessionFactory() );
|
||||
|
||||
if ( type.isAssociationType() ) {
|
||||
// we build the association-key here because of the "goofiness" with 'currentColumnPosition'
|
||||
final AssociationKey associationKey;
|
||||
final AssociationType aType = (AssociationType) type;
|
||||
final Joinable joinable = aType.getAssociatedJoinable( sessionFactory() );
|
||||
if ( aType.getForeignKeyDirection() == ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT ) {
|
||||
associationKey = new AssociationKey(
|
||||
getLHSTableName(
|
||||
aType,
|
||||
attributeNumber(),
|
||||
(OuterJoinLoadable) joinable
|
||||
),
|
||||
getLHSColumnNames(
|
||||
aType,
|
||||
attributeNumber(),
|
||||
columnPosition,
|
||||
(OuterJoinLoadable) joinable,
|
||||
sessionFactory()
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
associationKey = new AssociationKey(
|
||||
joinable.getTableName(),
|
||||
getRHSColumnNames( aType, sessionFactory() )
|
||||
);
|
||||
}
|
||||
|
||||
return new CompositeBasedAssociationAttribute(
|
||||
AbstractCompositeDefinition.this,
|
||||
sessionFactory(),
|
||||
currentAttributeNumber,
|
||||
name,
|
||||
(AssociationType) type,
|
||||
new BaselineAttributeInformation.Builder()
|
||||
.setInsertable( AbstractCompositeDefinition.this.isInsertable() )
|
||||
.setUpdateable( AbstractCompositeDefinition.this.isUpdateable() )
|
||||
.setInsertGenerated( AbstractCompositeDefinition.this.isInsertGenerated() )
|
||||
.setUpdateGenerated( AbstractCompositeDefinition.this.isUpdateGenerated() )
|
||||
.setNullable( getType().getPropertyNullability()[currentAttributeNumber] )
|
||||
.setDirtyCheckable( true )
|
||||
.setVersionable( AbstractCompositeDefinition.this.isVersionable() )
|
||||
.setCascadeStyle( getType().getCascadeStyle( currentAttributeNumber ) )
|
||||
.setFetchMode( getType().getFetchMode( currentAttributeNumber ) )
|
||||
.createInformation(),
|
||||
AbstractCompositeDefinition.this.attributeNumber(),
|
||||
associationKey
|
||||
);
|
||||
}
|
||||
else if ( type.isComponentType() ) {
|
||||
return new CompositeBasedCompositeAttribute(
|
||||
AbstractCompositeDefinition.this,
|
||||
sessionFactory(),
|
||||
currentAttributeNumber,
|
||||
name,
|
||||
(CompositeType) type,
|
||||
new BaselineAttributeInformation.Builder()
|
||||
.setInsertable( AbstractCompositeDefinition.this.isInsertable() )
|
||||
.setUpdateable( AbstractCompositeDefinition.this.isUpdateable() )
|
||||
.setInsertGenerated( AbstractCompositeDefinition.this.isInsertGenerated() )
|
||||
.setUpdateGenerated( AbstractCompositeDefinition.this.isUpdateGenerated() )
|
||||
.setNullable( getType().getPropertyNullability()[currentAttributeNumber] )
|
||||
.setDirtyCheckable( true )
|
||||
.setVersionable( AbstractCompositeDefinition.this.isVersionable() )
|
||||
.setCascadeStyle( getType().getCascadeStyle( currentAttributeNumber ) )
|
||||
.setFetchMode( getType().getFetchMode( currentAttributeNumber ) )
|
||||
.createInformation()
|
||||
);
|
||||
}
|
||||
else {
|
||||
return new CompositeBasedBasicAttribute(
|
||||
AbstractCompositeDefinition.this,
|
||||
sessionFactory(),
|
||||
currentAttributeNumber,
|
||||
name,
|
||||
type,
|
||||
new BaselineAttributeInformation.Builder()
|
||||
.setInsertable( AbstractCompositeDefinition.this.isInsertable() )
|
||||
.setUpdateable( AbstractCompositeDefinition.this.isUpdateable() )
|
||||
.setInsertGenerated( AbstractCompositeDefinition.this.isInsertGenerated() )
|
||||
.setUpdateGenerated( AbstractCompositeDefinition.this.isUpdateGenerated() )
|
||||
.setNullable( getType().getPropertyNullability()[currentAttributeNumber] )
|
||||
.setDirtyCheckable( true )
|
||||
.setVersionable( AbstractCompositeDefinition.this.isVersionable() )
|
||||
.setCascadeStyle( getType().getCascadeStyle( currentAttributeNumber ) )
|
||||
.setFetchMode( getType().getFetchMode( currentAttributeNumber ) )
|
||||
.createInformation()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException( "Remove operation not supported here" );
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public EntityPersister locateOwningPersister() {
|
||||
if ( EntityDefinition.class.isInstance( getSource() ) ) {
|
||||
return ( (EntityDefinition) getSource() ).getEntityPersister();
|
||||
}
|
||||
else {
|
||||
return ( (AbstractCompositeDefinition) getSource() ).locateOwningPersister();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,8 +32,8 @@ import org.hibernate.EntityMode;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.tuple.PropertyFactory;
|
||||
import org.hibernate.tuple.StandardProperty;
|
||||
import org.hibernate.tuple.PropertyFactory;
|
||||
|
||||
/**
|
||||
* Centralizes metamodel information about a component.
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple.component;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Joinable;
|
||||
import org.hibernate.persister.walking.internal.Helper;
|
||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.AssociationKey;
|
||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CompositeBasedAssociationAttribute
|
||||
extends AbstractCompositeBasedAttribute
|
||||
implements AssociationAttributeDefinition {
|
||||
|
||||
private final AssociationKey associationKey;
|
||||
private Joinable joinable;
|
||||
|
||||
public CompositeBasedAssociationAttribute(
|
||||
AbstractCompositeDefinition source,
|
||||
SessionFactoryImplementor factory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
AssociationType attributeType,
|
||||
BaselineAttributeInformation baselineInfo,
|
||||
int ownerAttributeNumber,
|
||||
AssociationKey associationKey) {
|
||||
super( source, factory, attributeNumber, attributeName, attributeType, baselineInfo, ownerAttributeNumber );
|
||||
this.associationKey = associationKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssociationType getType() {
|
||||
return (AssociationType) super.getType();
|
||||
}
|
||||
|
||||
protected Joinable getJoinable() {
|
||||
if ( joinable == null ) {
|
||||
joinable = getType().getAssociatedJoinable( sessionFactory() );
|
||||
}
|
||||
return joinable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssociationKey getAssociationKey() {
|
||||
return associationKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollection() {
|
||||
return getJoinable().isCollection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDefinition toEntityDefinition() {
|
||||
if ( isCollection() ) {
|
||||
throw new IllegalStateException( "Cannot treat collection attribute as entity type" );
|
||||
}
|
||||
return (EntityPersister) getJoinable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionDefinition toCollectionDefinition() {
|
||||
if ( isCollection() ) {
|
||||
throw new IllegalStateException( "Cannot treat entity attribute as collection type" );
|
||||
}
|
||||
return (CollectionPersister) getJoinable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath) {
|
||||
final EntityPersister owningPersister = locateOwningPersister();
|
||||
|
||||
FetchStyle style = determineFetchStyleByProfile(
|
||||
loadQueryInfluencers,
|
||||
owningPersister,
|
||||
propertyPath,
|
||||
ownerAttributeNumber()
|
||||
);
|
||||
if ( style == null ) {
|
||||
style = determineFetchStyleByMetadata(
|
||||
getSource().getType().getFetchMode( attributeNumber() ),
|
||||
getType()
|
||||
);
|
||||
}
|
||||
|
||||
return new FetchStrategy( determineFetchTiming( style ), style );
|
||||
}
|
||||
|
||||
protected FetchStyle determineFetchStyleByProfile(
|
||||
LoadQueryInfluencers loadQueryInfluencers,
|
||||
EntityPersister owningPersister,
|
||||
PropertyPath propertyPath,
|
||||
int ownerAttributeNumber) {
|
||||
return Helper.determineFetchStyleByProfile(
|
||||
loadQueryInfluencers,
|
||||
owningPersister,
|
||||
propertyPath,
|
||||
ownerAttributeNumber
|
||||
);
|
||||
}
|
||||
|
||||
protected FetchStyle determineFetchStyleByMetadata(FetchMode fetchMode, AssociationType type) {
|
||||
return Helper.determineFetchStyleByMetadata( fetchMode, type, sessionFactory() );
|
||||
}
|
||||
|
||||
private FetchTiming determineFetchTiming(FetchStyle style) {
|
||||
return Helper.determineFetchTiming( style, getType(), sessionFactory() );
|
||||
}
|
||||
|
||||
private EntityPersister locateOwningPersister() {
|
||||
return getSource().locateOwningPersister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CascadeStyle determineCascadeStyle() {
|
||||
final CompositeType compositeType = (CompositeType) locateOwningPersister().getPropertyType( getName() );
|
||||
return compositeType.getCascadeStyle( attributeNumber() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple.component;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.walking.spi.AttributeSource;
|
||||
import org.hibernate.tuple.AbstractNonIdentifierAttribute;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CompositeBasedBasicAttribute extends AbstractNonIdentifierAttribute {
|
||||
protected CompositeBasedBasicAttribute(
|
||||
AttributeSource source,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
Type attributeType,
|
||||
BaselineAttributeInformation baselineInfo) {
|
||||
super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple.component;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.walking.spi.CompositeDefinition;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.type.CompositeType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CompositeBasedCompositeAttribute
|
||||
extends AbstractCompositeDefinition
|
||||
implements CompositeDefinition {
|
||||
public CompositeBasedCompositeAttribute(
|
||||
CompositeDefinition source,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
CompositeType attributeType,
|
||||
BaselineAttributeInformation baselineInfo) {
|
||||
super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple.entity;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.tuple.AbstractNonIdentifierAttribute;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractEntityBasedAttribute extends AbstractNonIdentifierAttribute {
|
||||
protected AbstractEntityBasedAttribute(
|
||||
EntityPersister source,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
Type attributeType,
|
||||
BaselineAttributeInformation attributeInformation) {
|
||||
super( source, sessionFactory, attributeNumber, attributeName, attributeType, attributeInformation );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister getSource() {
|
||||
return (EntityPersister) super.getSource();
|
||||
}
|
||||
}
|
|
@ -56,8 +56,9 @@ import org.hibernate.property.Setter;
|
|||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.ProxyFactory;
|
||||
import org.hibernate.tuple.Instantiator;
|
||||
import org.hibernate.tuple.NonIdentifierAttribute;
|
||||
import org.hibernate.tuple.StandardProperty;
|
||||
import org.hibernate.tuple.VersionProperty;
|
||||
import org.hibernate.tuple.entity.VersionProperty;
|
||||
import org.hibernate.type.ComponentType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
@ -604,7 +605,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
final Object[] result = new Object[span];
|
||||
|
||||
for ( int j = 0; j < span; j++ ) {
|
||||
StandardProperty property = entityMetamodel.getProperties()[j];
|
||||
NonIdentifierAttribute property = entityMetamodel.getProperties()[j];
|
||||
if ( getAll || !property.isLazy() ) {
|
||||
result[j] = getters[j].get( entity );
|
||||
}
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
package org.hibernate.tuple.entity;
|
||||
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.PropertyPath;
|
||||
import org.hibernate.persister.collection.QueryableCollection;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.Joinable;
|
||||
import org.hibernate.persister.entity.OuterJoinLoadable;
|
||||
import org.hibernate.persister.walking.internal.Helper;
|
||||
import org.hibernate.persister.walking.spi.AssociationAttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.AssociationKey;
|
||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.ForeignKeyDirection;
|
||||
|
||||
import static org.hibernate.engine.internal.JoinHelper.getLHSColumnNames;
|
||||
import static org.hibernate.engine.internal.JoinHelper.getLHSTableName;
|
||||
import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityBasedAssociationAttribute
|
||||
extends AbstractEntityBasedAttribute
|
||||
implements AssociationAttributeDefinition {
|
||||
|
||||
private Joinable joinable;
|
||||
|
||||
public EntityBasedAssociationAttribute(
|
||||
EntityPersister source,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
AssociationType attributeType,
|
||||
BaselineAttributeInformation baselineInfo) {
|
||||
super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo );
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssociationType getType() {
|
||||
return (AssociationType) super.getType();
|
||||
}
|
||||
|
||||
protected Joinable getJoinable() {
|
||||
if ( joinable == null ) {
|
||||
joinable = getType().getAssociatedJoinable( sessionFactory() );
|
||||
}
|
||||
return joinable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssociationKey getAssociationKey() {
|
||||
final AssociationType type = getType();
|
||||
final Joinable joinable = type.getAssociatedJoinable( sessionFactory() );
|
||||
|
||||
if ( type.getForeignKeyDirection() == ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT ) {
|
||||
final String lhsTableName;
|
||||
final String[] lhsColumnNames;
|
||||
|
||||
if ( joinable.isCollection() ) {
|
||||
final QueryableCollection collectionPersister = (QueryableCollection) joinable;
|
||||
lhsTableName = collectionPersister.getTableName();
|
||||
lhsColumnNames = collectionPersister.getElementColumnNames();
|
||||
}
|
||||
else {
|
||||
final OuterJoinLoadable entityPersister = (OuterJoinLoadable) joinable;
|
||||
lhsTableName = getLHSTableName( type, attributeNumber(), entityPersister );
|
||||
lhsColumnNames = getLHSColumnNames( type, attributeNumber(), entityPersister, sessionFactory() );
|
||||
}
|
||||
return new AssociationKey( lhsTableName, lhsColumnNames );
|
||||
}
|
||||
else {
|
||||
return new AssociationKey( joinable.getTableName(), getRHSColumnNames( type, sessionFactory() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollection() {
|
||||
return getJoinable().isCollection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDefinition toEntityDefinition() {
|
||||
if ( isCollection() ) {
|
||||
throw new IllegalStateException( "Cannot treat collection-valued attribute as entity type" );
|
||||
}
|
||||
return (EntityPersister) getJoinable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionDefinition toCollectionDefinition() {
|
||||
if ( ! isCollection() ) {
|
||||
throw new IllegalStateException( "Cannot treat entity-valued attribute as collection type" );
|
||||
}
|
||||
return (QueryableCollection) getJoinable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath) {
|
||||
final EntityPersister owningPersister = getSource().getEntityPersister();
|
||||
|
||||
FetchStyle style = Helper.determineFetchStyleByProfile(
|
||||
loadQueryInfluencers,
|
||||
owningPersister,
|
||||
propertyPath,
|
||||
attributeNumber()
|
||||
);
|
||||
if ( style == null ) {
|
||||
style = Helper.determineFetchStyleByMetadata(
|
||||
((OuterJoinLoadable) getSource().getEntityPersister()).getFetchMode( attributeNumber() ),
|
||||
getType(),
|
||||
sessionFactory()
|
||||
);
|
||||
}
|
||||
|
||||
return new FetchStrategy(
|
||||
Helper.determineFetchTiming( style, getType(), sessionFactory() ),
|
||||
style
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CascadeStyle determineCascadeStyle() {
|
||||
return getSource().getEntityPersister().getPropertyCascadeStyles()[attributeNumber()];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple.entity;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityBasedBasicAttribute extends AbstractEntityBasedAttribute {
|
||||
public EntityBasedBasicAttribute(
|
||||
EntityPersister source,
|
||||
SessionFactoryImplementor factory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
Type attributeType,
|
||||
BaselineAttributeInformation baselineInfo) {
|
||||
super( source, factory, attributeNumber, attributeName, attributeType, baselineInfo );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple.entity;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.tuple.component.AbstractCompositeDefinition;
|
||||
import org.hibernate.persister.walking.spi.CompositeDefinition;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.type.CompositeType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntityBasedCompositeAttribute
|
||||
extends AbstractCompositeDefinition
|
||||
implements CompositeDefinition {
|
||||
|
||||
public EntityBasedCompositeAttribute(
|
||||
EntityPersister source,
|
||||
SessionFactoryImplementor factory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
CompositeType attributeType,
|
||||
BaselineAttributeInformation baselineInfo) {
|
||||
super( source, factory, attributeNumber, attributeName, attributeType, baselineInfo );
|
||||
}
|
||||
}
|
|
@ -57,10 +57,12 @@ import org.hibernate.metamodel.binding.BasicAttributeBinding;
|
|||
import org.hibernate.metamodel.binding.EntityBinding;
|
||||
import org.hibernate.metamodel.domain.Attribute;
|
||||
import org.hibernate.metamodel.domain.SingularAttribute;
|
||||
import org.hibernate.persister.entity.AbstractEntityPersister;
|
||||
import org.hibernate.tuple.IdentifierProperty;
|
||||
import org.hibernate.tuple.NonIdentifierAttribute;
|
||||
import org.hibernate.tuple.PropertyFactory;
|
||||
import org.hibernate.tuple.StandardProperty;
|
||||
import org.hibernate.tuple.VersionProperty;
|
||||
import org.hibernate.tuple.entity.VersionProperty;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
@ -78,17 +80,18 @@ public class EntityMetamodel implements Serializable {
|
|||
private static final int NO_VERSION_INDX = -66;
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
private final AbstractEntityPersister persister;
|
||||
|
||||
private final String name;
|
||||
private final String rootName;
|
||||
private final EntityType entityType;
|
||||
|
||||
private final IdentifierProperty identifierProperty;
|
||||
private final IdentifierProperty identifierAttribute;
|
||||
private final boolean versioned;
|
||||
|
||||
private final int propertySpan;
|
||||
private final int versionPropertyIndex;
|
||||
private final StandardProperty[] properties;
|
||||
private final NonIdentifierAttribute[] properties;
|
||||
// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
private final String[] propertyNames;
|
||||
private final Type[] propertyTypes;
|
||||
|
@ -136,17 +139,21 @@ public class EntityMetamodel implements Serializable {
|
|||
private final EntityTuplizer entityTuplizer;
|
||||
private final EntityInstrumentationMetadata instrumentationMetadata;
|
||||
|
||||
public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplementor sessionFactory) {
|
||||
public EntityMetamodel(
|
||||
PersistentClass persistentClass,
|
||||
AbstractEntityPersister persister,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.persister = persister;
|
||||
|
||||
name = persistentClass.getEntityName();
|
||||
rootName = persistentClass.getRootClass().getEntityName();
|
||||
entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne( name );
|
||||
|
||||
identifierProperty = PropertyFactory.buildIdentifierProperty(
|
||||
persistentClass,
|
||||
sessionFactory.getIdentifierGenerator( rootName )
|
||||
);
|
||||
identifierAttribute = PropertyFactory.buildIdentifierAttribute(
|
||||
persistentClass,
|
||||
sessionFactory.getIdentifierGenerator( rootName )
|
||||
);
|
||||
|
||||
versioned = persistentClass.isVersioned();
|
||||
|
||||
|
@ -157,7 +164,7 @@ public class EntityMetamodel implements Serializable {
|
|||
boolean hasLazy = false;
|
||||
|
||||
propertySpan = persistentClass.getPropertyClosureSpan();
|
||||
properties = new StandardProperty[propertySpan];
|
||||
properties = new NonIdentifierAttribute[propertySpan];
|
||||
List<Integer> naturalIdNumbers = new ArrayList<Integer>();
|
||||
// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
propertyNames = new String[propertySpan];
|
||||
|
@ -191,10 +198,22 @@ public class EntityMetamodel implements Serializable {
|
|||
|
||||
if ( prop == persistentClass.getVersion() ) {
|
||||
tempVersionProperty = i;
|
||||
properties[i] = PropertyFactory.buildVersionProperty( prop, instrumentationMetadata.isInstrumented() );
|
||||
properties[i] = PropertyFactory.buildVersionProperty(
|
||||
persister,
|
||||
sessionFactory,
|
||||
i,
|
||||
prop,
|
||||
instrumentationMetadata.isInstrumented()
|
||||
);
|
||||
}
|
||||
else {
|
||||
properties[i] = PropertyFactory.buildStandardProperty( prop, instrumentationMetadata.isInstrumented() );
|
||||
properties[i] = PropertyFactory.buildEntityBasedAttribute(
|
||||
persister,
|
||||
sessionFactory,
|
||||
i,
|
||||
prop,
|
||||
instrumentationMetadata.isInstrumented()
|
||||
);
|
||||
}
|
||||
|
||||
if ( prop.isNaturalIdentifier() ) {
|
||||
|
@ -363,15 +382,19 @@ public class EntityMetamodel implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public EntityMetamodel(EntityBinding entityBinding, SessionFactoryImplementor sessionFactory) {
|
||||
public EntityMetamodel(
|
||||
EntityBinding entityBinding,
|
||||
AbstractEntityPersister persister,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.persister = persister;
|
||||
|
||||
name = entityBinding.getEntity().getName();
|
||||
|
||||
rootName = entityBinding.getHierarchyDetails().getRootEntityBinding().getEntity().getName();
|
||||
entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne( name );
|
||||
|
||||
identifierProperty = PropertyFactory.buildIdentifierProperty(
|
||||
identifierAttribute = PropertyFactory.buildIdentifierProperty(
|
||||
entityBinding,
|
||||
sessionFactory.getIdentifierGenerator( rootName )
|
||||
);
|
||||
|
@ -398,7 +421,7 @@ public class EntityMetamodel implements Serializable {
|
|||
entityBinding.getAttributeBindingClosureSpan() :
|
||||
entityBinding.getAttributeBindingClosureSpan() - 1;
|
||||
|
||||
properties = new StandardProperty[propertySpan];
|
||||
properties = new NonIdentifierAttribute[propertySpan];
|
||||
List naturalIdNumbers = new ArrayList();
|
||||
// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
propertyNames = new String[propertySpan];
|
||||
|
@ -435,6 +458,7 @@ public class EntityMetamodel implements Serializable {
|
|||
if ( attributeBinding == entityBinding.getHierarchyDetails().getVersioningAttributeBinding() ) {
|
||||
tempVersionProperty = i;
|
||||
properties[i] = PropertyFactory.buildVersionProperty(
|
||||
persister,
|
||||
entityBinding.getHierarchyDetails().getVersioningAttributeBinding(),
|
||||
instrumentationMetadata.isInstrumented()
|
||||
);
|
||||
|
@ -595,7 +619,7 @@ public class EntityMetamodel implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private ValueInclusion determineInsertValueGenerationType(Property mappingProperty, StandardProperty runtimeProperty) {
|
||||
private ValueInclusion determineInsertValueGenerationType(Property mappingProperty, NonIdentifierAttribute runtimeProperty) {
|
||||
if ( runtimeProperty.isInsertGenerated() ) {
|
||||
return ValueInclusion.FULL;
|
||||
}
|
||||
|
@ -607,7 +631,7 @@ public class EntityMetamodel implements Serializable {
|
|||
return ValueInclusion.NONE;
|
||||
}
|
||||
|
||||
private ValueInclusion determineInsertValueGenerationType(AttributeBinding mappingProperty, StandardProperty runtimeProperty) {
|
||||
private ValueInclusion determineInsertValueGenerationType(AttributeBinding mappingProperty, NonIdentifierAttribute runtimeProperty) {
|
||||
if ( runtimeProperty.isInsertGenerated() ) {
|
||||
return ValueInclusion.FULL;
|
||||
}
|
||||
|
@ -636,7 +660,7 @@ public class EntityMetamodel implements Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
private ValueInclusion determineUpdateValueGenerationType(Property mappingProperty, StandardProperty runtimeProperty) {
|
||||
private ValueInclusion determineUpdateValueGenerationType(Property mappingProperty, NonIdentifierAttribute runtimeProperty) {
|
||||
if ( runtimeProperty.isUpdateGenerated() ) {
|
||||
return ValueInclusion.FULL;
|
||||
}
|
||||
|
@ -648,7 +672,7 @@ public class EntityMetamodel implements Serializable {
|
|||
return ValueInclusion.NONE;
|
||||
}
|
||||
|
||||
private ValueInclusion determineUpdateValueGenerationType(AttributeBinding mappingProperty, StandardProperty runtimeProperty) {
|
||||
private ValueInclusion determineUpdateValueGenerationType(AttributeBinding mappingProperty, NonIdentifierAttribute runtimeProperty) {
|
||||
if ( runtimeProperty.isUpdateGenerated() ) {
|
||||
return ValueInclusion.FULL;
|
||||
}
|
||||
|
@ -762,7 +786,7 @@ public class EntityMetamodel implements Serializable {
|
|||
}
|
||||
|
||||
public IdentifierProperty getIdentifierProperty() {
|
||||
return identifierProperty;
|
||||
return identifierAttribute;
|
||||
}
|
||||
|
||||
public int getPropertySpan() {
|
||||
|
@ -782,7 +806,7 @@ public class EntityMetamodel implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public StandardProperty[] getProperties() {
|
||||
public NonIdentifierAttribute[] getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tuple.entity;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.VersionValue;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.tuple.AbstractNonIdentifierAttribute;
|
||||
import org.hibernate.tuple.BaselineAttributeInformation;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Represents a version property within the Hibernate runtime-metamodel.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class VersionProperty extends AbstractNonIdentifierAttribute {
|
||||
|
||||
private final VersionValue unsavedValue;
|
||||
|
||||
/**
|
||||
* Constructs VersionProperty instances.
|
||||
*
|
||||
* @param source Reference back to the source of this attribute (the persister)
|
||||
* @param sessionFactory The session factory this is part of.
|
||||
* @param attributeNumber The attribute number within thje
|
||||
* @param attributeName The name by which the property can be referenced within
|
||||
* its owner.
|
||||
* @param attributeType The Hibernate Type of this property.
|
||||
* @param attributeInformation The basic attribute information.
|
||||
* @param unsavedValue The value which, if found as the value of
|
||||
* this (i.e., the version) property, represents new (i.e., un-saved)
|
||||
* instances of the owning entity.
|
||||
*/
|
||||
public VersionProperty(
|
||||
EntityPersister source,
|
||||
SessionFactoryImplementor sessionFactory,
|
||||
int attributeNumber,
|
||||
String attributeName,
|
||||
Type attributeType,
|
||||
BaselineAttributeInformation attributeInformation, VersionValue unsavedValue) {
|
||||
super( source, sessionFactory, attributeNumber, attributeName, attributeType, attributeInformation );
|
||||
this.unsavedValue = unsavedValue;
|
||||
}
|
||||
|
||||
public VersionValue getUnsavedValue() {
|
||||
return unsavedValue;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ import java.util.Map;
|
|||
import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.property.BackrefPropertyAccessor;
|
||||
import org.hibernate.tuple.StandardProperty;
|
||||
import org.hibernate.tuple.NonIdentifierAttribute;
|
||||
|
||||
/**
|
||||
* Collection of convenience methods relating to operations across arrays of types...
|
||||
|
@ -280,7 +280,7 @@ public class TypeHelper {
|
|||
* @return Array containing indices of the dirty properties, or null if no properties considered dirty.
|
||||
*/
|
||||
public static int[] findDirty(
|
||||
final StandardProperty[] properties,
|
||||
final NonIdentifierAttribute[] properties,
|
||||
final Object[] currentState,
|
||||
final Object[] previousState,
|
||||
final boolean[][] includeColumns,
|
||||
|
@ -328,7 +328,7 @@ public class TypeHelper {
|
|||
* @return Array containing indices of the modified properties, or null if no properties considered modified.
|
||||
*/
|
||||
public static int[] findModified(
|
||||
final StandardProperty[] properties,
|
||||
final NonIdentifierAttribute[] properties,
|
||||
final Object[] currentState,
|
||||
final Object[] previousState,
|
||||
final boolean[][] includeColumns,
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.loader.plan.spi;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.CascadingActions;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.loader.plan.internal.CascadeLoadPlanBuilderStrategy;
|
||||
import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.testing.junit4.ExtraAssertions;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LoadPlanBuilderTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { Message.class, Poster.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleBuild() {
|
||||
EntityPersister ep = (EntityPersister) sessionFactory().getClassMetadata(Message.class);
|
||||
SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy(
|
||||
sessionFactory(),
|
||||
LoadQueryInfluencers.NONE,
|
||||
"abc",
|
||||
0
|
||||
);
|
||||
LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, ep );
|
||||
assertFalse( plan.hasAnyScalarReturns() );
|
||||
assertEquals( 1, plan.getReturns().size() );
|
||||
Return rtn = plan.getReturns().get( 0 );
|
||||
EntityReturn entityReturn = ExtraAssertions.assertTyping( EntityReturn.class, rtn );
|
||||
assertEquals( "abc", entityReturn.getAlias() );
|
||||
assertNotNull( entityReturn.getFetches() );
|
||||
assertEquals( 1, entityReturn.getFetches().length );
|
||||
Fetch fetch = entityReturn.getFetches()[0];
|
||||
EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch );
|
||||
assertNotNull( entityFetch.getFetches() );
|
||||
assertEquals( 0, entityFetch.getFetches().length );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCascadeBasedBuild() {
|
||||
EntityPersister ep = (EntityPersister) sessionFactory().getClassMetadata(Message.class);
|
||||
CascadeLoadPlanBuilderStrategy strategy = new CascadeLoadPlanBuilderStrategy(
|
||||
CascadingActions.MERGE,
|
||||
sessionFactory(),
|
||||
LoadQueryInfluencers.NONE,
|
||||
"abc",
|
||||
0
|
||||
);
|
||||
LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, ep );
|
||||
assertFalse( plan.hasAnyScalarReturns() );
|
||||
assertEquals( 1, plan.getReturns().size() );
|
||||
Return rtn = plan.getReturns().get( 0 );
|
||||
EntityReturn entityReturn = ExtraAssertions.assertTyping( EntityReturn.class, rtn );
|
||||
assertEquals( "abc", entityReturn.getAlias() );
|
||||
assertNotNull( entityReturn.getFetches() );
|
||||
assertEquals( 1, entityReturn.getFetches().length );
|
||||
Fetch fetch = entityReturn.getFetches()[0];
|
||||
EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch );
|
||||
assertNotNull( entityFetch.getFetches() );
|
||||
assertEquals( 0, entityFetch.getFetches().length );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollectionInitializerCase() {
|
||||
CollectionPersister cp = sessionFactory().getCollectionPersister( Poster.class.getName() + ".messages" );
|
||||
SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy(
|
||||
sessionFactory(),
|
||||
LoadQueryInfluencers.NONE,
|
||||
"abc",
|
||||
0
|
||||
);
|
||||
LoadPlan plan = LoadPlanBuilder.buildRootCollectionLoadPlan( strategy, cp );
|
||||
assertFalse( plan.hasAnyScalarReturns() );
|
||||
assertEquals( 1, plan.getReturns().size() );
|
||||
Return rtn = plan.getReturns().get( 0 );
|
||||
CollectionReturn collectionReturn = ExtraAssertions.assertTyping( CollectionReturn.class, rtn );
|
||||
assertEquals( "abc", collectionReturn.getAlias() );
|
||||
|
||||
assertNotNull( collectionReturn.getFetches() );
|
||||
assertEquals( 1, collectionReturn.getFetches().length ); // the collection elements are fetched
|
||||
Fetch fetch = collectionReturn.getFetches()[0];
|
||||
EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch );
|
||||
assertNotNull( entityFetch.getFetches() );
|
||||
assertEquals( 0, entityFetch.getFetches().length );
|
||||
}
|
||||
|
||||
@Entity( name = "Message" )
|
||||
public static class Message {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String name;
|
||||
@ManyToOne( cascade = CascadeType.MERGE )
|
||||
@JoinColumn
|
||||
private Poster poster;
|
||||
}
|
||||
|
||||
@Entity( name = "Poster" )
|
||||
public static class Poster {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String name;
|
||||
@OneToMany(mappedBy = "poster")
|
||||
private List<Message> messages;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* jDocBook, processing of DocBook sources
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.persister.walking;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.common.util.StringHelper;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.walking.spi.AssociationVisitationStrategy;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionDefinition;
|
||||
import org.hibernate.persister.walking.spi.CompositeDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityDefinition;
|
||||
import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicWalkingTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { Message.class, Poster.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIt() {
|
||||
EntityPersister ep = (EntityPersister) sessionFactory().getClassMetadata(Message.class);
|
||||
MetadataDrivenModelGraphVisitor.visitEntity(
|
||||
new AssociationVisitationStrategy() {
|
||||
private int depth = 0;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
System.out.println( ">> Start" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
System.out.println( "<< Finish" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingEntity(EntityDefinition entityDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Starting entity (%s)",
|
||||
StringHelper.repeat( ">>", ++depth ),
|
||||
entityDefinition.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingEntity(EntityDefinition entityDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Finishing entity (%s)",
|
||||
StringHelper.repeat( "<<", depth-- ),
|
||||
entityDefinition.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingCollection(CollectionDefinition collectionDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Starting collection (%s)",
|
||||
StringHelper.repeat( ">>", ++depth ),
|
||||
collectionDefinition.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingCollection(CollectionDefinition collectionDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Finishing collection (%s)",
|
||||
StringHelper.repeat( ">>", depth-- ),
|
||||
collectionDefinition.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startingComposite(CompositeDefinition compositeDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Starting composite (%s)",
|
||||
StringHelper.repeat( ">>", ++depth ),
|
||||
compositeDefinition.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingComposite(CompositeDefinition compositeDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Finishing composite (%s)",
|
||||
StringHelper.repeat( ">>", depth-- ),
|
||||
compositeDefinition.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startingAttribute(AttributeDefinition attributeDefinition) {
|
||||
System.out.println(
|
||||
String.format(
|
||||
"%s Handling attribute (%s)",
|
||||
StringHelper.repeat( ">>", depth + 1 ),
|
||||
attributeDefinition.toString()
|
||||
)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishingAttribute(AttributeDefinition attributeDefinition) {
|
||||
// nothing to do
|
||||
}
|
||||
},
|
||||
ep
|
||||
);
|
||||
}
|
||||
|
||||
@Entity( name = "Message" )
|
||||
public static class Message {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String name;
|
||||
@ManyToOne
|
||||
@JoinColumn
|
||||
private Poster poster;
|
||||
}
|
||||
|
||||
@Entity( name = "Poster" )
|
||||
public static class Poster {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String name;
|
||||
@OneToMany(mappedBy = "poster")
|
||||
private List<Message> messages;
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
|||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.entry.CacheEntry;
|
||||
import org.hibernate.cache.spi.entry.CacheEntryStructure;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
|
@ -54,6 +55,9 @@ import org.hibernate.metamodel.binding.PluralAttributeBinding;
|
|||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.spi.PersisterClassResolver;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
import org.hibernate.tuple.entity.NonPojoInstrumentationMetadata;
|
||||
|
@ -579,6 +583,21 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
|
|||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister getEntityPersister() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AttributeDefinition> getEmbeddedCompositeIdentifierAttributes() {
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AttributeDefinition> getAttributes() {
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public static class NoopCollectionPersister implements CollectionPersister {
|
||||
|
@ -606,8 +625,23 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
|
|||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionPersister getCollectionPersister() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CollectionType getCollectionType() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionIndexDefinition getIndexDefinition() {
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionElementDefinition getElementDefinition() {
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
|
||||
public Type getKeyType() {
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.cache.spi.entry.CacheEntry;
|
|||
import org.hibernate.cache.spi.entry.CacheEntryStructure;
|
||||
import org.hibernate.cache.spi.entry.StandardCacheEntryImpl;
|
||||
import org.hibernate.cache.spi.entry.UnstructuredCacheEntry;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.engine.internal.TwoPhaseLoad;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
|
@ -34,6 +35,7 @@ import org.hibernate.internal.util.compare.EqualsHelper;
|
|||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metadata.ClassMetadata;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
import org.hibernate.tuple.entity.NonPojoInstrumentationMetadata;
|
||||
|
@ -671,4 +673,19 @@ public class CustomPersister implements EntityPersister {
|
|||
public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) {
|
||||
return new StaticFilterAliasGenerator(rootAlias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister getEntityPersister() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AttributeDefinition> getEmbeddedCompositeIdentifierAttributes() {
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AttributeDefinition> getAttributes() {
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue