HHH-3512 : id generator short-naming

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@15366 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2008-10-21 19:10:17 +00:00
parent 84c4579520
commit b24a10209a
15 changed files with 216 additions and 74 deletions

View File

@ -27,7 +27,7 @@ package org.hibernate.engine;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.id.IdentifierGeneratorFactory; import org.hibernate.id.IdentifierGeneratorHelper;
/** /**
* A strategy for determining if a version value is an version of * A strategy for determining if a version value is an version of
@ -91,7 +91,7 @@ public class VersionValue {
} }
} }
public Object getDefaultValue(Object currentValue) { public Object getDefaultValue(Object currentValue) {
return IdentifierGeneratorFactory.createNumber( -1l, currentValue.getClass() ); return IdentifierGeneratorHelper.createNumber( -1l, currentValue.getClass() );
} }
public String toString() { public String toString() {
return "VERSION_NEGATIVE"; return "VERSION_NEGATIVE";

View File

@ -47,7 +47,7 @@ import org.hibernate.engine.Status;
import org.hibernate.engine.Versioning; import org.hibernate.engine.Versioning;
import org.hibernate.event.EventSource; import org.hibernate.event.EventSource;
import org.hibernate.id.IdentifierGenerationException; import org.hibernate.id.IdentifierGenerationException;
import org.hibernate.id.IdentifierGeneratorFactory; import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.intercept.FieldInterceptionHelper; import org.hibernate.intercept.FieldInterceptionHelper;
import org.hibernate.intercept.FieldInterceptor; import org.hibernate.intercept.FieldInterceptor;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
@ -123,10 +123,10 @@ public abstract class AbstractSaveEventListener extends AbstractReassociateEvent
if ( generatedId == null ) { if ( generatedId == null ) {
throw new IdentifierGenerationException( "null id generated for:" + entity.getClass() ); throw new IdentifierGenerationException( "null id generated for:" + entity.getClass() );
} }
else if ( generatedId == IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR ) { else if ( generatedId == IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR ) {
return source.getIdentifier( entity ); return source.getIdentifier( entity );
} }
else if ( generatedId == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) { else if ( generatedId == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) {
return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess ); return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess );
} }
else { else {

View File

@ -39,6 +39,6 @@ public abstract class AbstractPostInsertGenerator implements PostInsertIdentifie
* {@inheritDoc} * {@inheritDoc}
*/ */
public Serializable generate(SessionImplementor s, Object obj) { public Serializable generate(SessionImplementor s, Object obj) {
return IdentifierGeneratorFactory.POST_INSERT_INDICATOR; return IdentifierGeneratorHelper.POST_INSERT_INDICATOR;
} }
} }

View File

@ -27,7 +27,6 @@ package org.hibernate.id;
import java.io.Serializable; import java.io.Serializable;
import java.util.Properties; import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.TransientObjectException; import org.hibernate.TransientObjectException;
@ -48,27 +47,61 @@ import org.hibernate.type.Type;
* @author Gavin King * @author Gavin King
*/ */
public class ForeignGenerator implements IdentifierGenerator, Configurable { public class ForeignGenerator implements IdentifierGenerator, Configurable {
private String propertyName;
private String entityName; private String entityName;
private String propertyName;
/** /**
* @see org.hibernate.id.IdentifierGenerator#generate(org.hibernate.engine.SessionImplementor, java.lang.Object) * Getter for property 'entityName'.
*
* @return Value for property 'entityName'.
*/ */
public Serializable generate(SessionImplementor sessionImplementor, Object object) public String getEntityName() {
throws HibernateException { return entityName;
}
Session session = (Session) sessionImplementor;
/**
* Getter for property 'propertyName'.
*
* @return Value for property 'propertyName'.
*/
public String getPropertyName() {
return propertyName;
}
/**
* Getter for property 'role'. Role is the {@link #getPropertyName property name} qualified by the
* {@link #getEntityName entity name}.
*
* @return Value for property 'role'.
*/
public String getRole() {
return getEntityName() + '.' + getPropertyName();
}
/**
* {@inheritDoc}
*/
public void configure(Type type, Properties params, Dialect d) {
propertyName = params.getProperty( "property" );
entityName = params.getProperty( ENTITY_NAME );
if ( propertyName==null ) {
throw new MappingException( "param named \"property\" is required for foreign id generation strategy" );
}
}
/**
* {@inheritDoc}
*/
public Serializable generate(SessionImplementor sessionImplementor, Object object) {
Session session = ( Session ) sessionImplementor;
Object associatedObject = sessionImplementor.getFactory() Object associatedObject = sessionImplementor.getFactory()
.getClassMetadata( entityName ) .getClassMetadata( entityName )
.getPropertyValue( object, propertyName, session.getEntityMode() ); .getPropertyValue( object, propertyName, session.getEntityMode() );
if ( associatedObject == null ) { if ( associatedObject == null ) {
throw new IdentifierGenerationException( throw new IdentifierGenerationException(
"attempted to assign id from null one-to-one property: " + "attempted to assign id from null one-to-one property [" + getRole() + "]"
propertyName );
);
} }
EntityType type = (EntityType) sessionImplementor.getFactory() EntityType type = (EntityType) sessionImplementor.getFactory()
@ -81,7 +114,7 @@ public class ForeignGenerator implements IdentifierGenerator, Configurable {
type.getAssociatedEntityName(), type.getAssociatedEntityName(),
associatedObject, associatedObject,
sessionImplementor sessionImplementor
); );
} }
catch (TransientObjectException toe) { catch (TransientObjectException toe) {
id = session.save( type.getAssociatedEntityName(), associatedObject ); id = session.save( type.getAssociatedEntityName(), associatedObject );
@ -89,23 +122,9 @@ public class ForeignGenerator implements IdentifierGenerator, Configurable {
if ( session.contains(object) ) { if ( session.contains(object) ) {
//abort the save (the object is already saved by a circular cascade) //abort the save (the object is already saved by a circular cascade)
return IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR; return IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR;
//throw new IdentifierGenerationException("save associated object first, or disable cascade for inverse association"); //throw new IdentifierGenerationException("save associated object first, or disable cascade for inverse association");
} }
return id; return id;
} }
/**
* @see org.hibernate.id.Configurable#configure(org.hibernate.type.Type, java.util.Properties, org.hibernate.dialect.Dialect)
*/
public void configure(Type type, Properties params, Dialect d)
throws MappingException {
propertyName = params.getProperty("property");
entityName = params.getProperty(ENTITY_NAME);
if (propertyName==null) throw new MappingException(
"param named \"property\" is required for foreign id generation strategy"
);
}
} }

View File

@ -0,0 +1,145 @@
/*
* 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.id;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException;
import org.hibernate.type.Type;
/**
* Factory and helper methods for <tt>IdentifierGenerator</tt> framework.
*
* @author Gavin King
*/
public final class IdentifierGeneratorHelper {
private static final Logger log = LoggerFactory.getLogger( IdentifierGeneratorHelper.class );
/**
* Marker object returned from {@link IdentifierGenerator#generate} to indicate that we should short-circuit any
* continued generated id checking. Currently this is only used in the case of the
* {@link org.hibernate.id.ForeignGenerator foreign} generator as a way to signal that we should use the associated
* entity's id value.
*/
public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() {
public String toString() {
return "SHORT_CIRCUIT_INDICATOR";
}
};
/**
* Marker object returned from {@link IdentifierGenerator#generate} to indicate that the entity's identifier will
* be generated as part of the datbase insertion.
*/
public static final Serializable POST_INSERT_INDICATOR = new Serializable() {
public String toString() {
return "POST_INSERT_INDICATOR";
}
};
/**
* Get the generated identifier when using identity columns
*
* @param rs The result set from which to extract the the generated identity.
* @param type The expected type mapping for the identity value.
* @return The generated identity value
* @throws SQLException Can be thrown while accessing the result set
* @throws HibernateException Indicates a problem reading back a generated identity value.
*/
public static Serializable getGeneratedIdentity(ResultSet rs, Type type) throws SQLException, HibernateException {
if ( !rs.next() ) {
throw new HibernateException( "The database returned no natively generated identity value" );
}
final Serializable id = IdentifierGeneratorHelper.get( rs, type );
log.debug( "Natively generated identity: " + id );
return id;
}
/**
* Extract the value from the result set (which is assumed to already have been positioned to the apopriate row)
* and wrp it in the appropriate Java numeric type.
*
* @param rs The result set from which to extract the value.
* @param type The expected type of the value.
* @return The extracted value.
* @throws SQLException Indicates problems access the result set
* @throws IdentifierGenerationException Indicates an unknown type.
*/
public static Serializable get(ResultSet rs, Type type) throws SQLException, IdentifierGenerationException {
Class clazz = type.getReturnedClass();
if ( clazz == Long.class ) {
return new Long( rs.getLong( 1 ) );
}
else if ( clazz == Integer.class ) {
return new Integer( rs.getInt( 1 ) );
}
else if ( clazz == Short.class ) {
return new Short( rs.getShort( 1 ) );
}
else if ( clazz == String.class ) {
return rs.getString( 1 );
}
else {
throw new IdentifierGenerationException( "this id generator generates long, integer, short or string" );
}
}
/**
* Wrap the given value in the given Java numeric class.
*
* @param value The primitive value to wrap.
* @param clazz The Java numeric type in which to wrap the value.
* @return The wrapped type.
* @throws IdentifierGenerationException Indicates an unhandled 'clazz'.
*/
public static Number createNumber(long value, Class clazz) throws IdentifierGenerationException {
if ( clazz == Long.class ) {
return new Long( value );
}
else if ( clazz == Integer.class ) {
return new Integer( ( int ) value );
}
else if ( clazz == Short.class ) {
return new Short( ( short ) value );
}
else {
throw new IdentifierGenerationException( "this id generator generates long, integer, short" );
}
}
/**
* Disallow instantiation of IdentifierGeneratorHelper.
*/
private IdentifierGeneratorHelper() {
}
}

View File

@ -95,7 +95,7 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
ResultSet rs = null; ResultSet rs = null;
try { try {
rs = insert.getGeneratedKeys(); rs = insert.getGeneratedKeys();
return IdentifierGeneratorFactory.getGeneratedIdentity( return IdentifierGeneratorHelper.getGeneratedIdentity(
rs, rs,
persister.getIdentifierType() persister.getIdentifierType()
); );
@ -142,7 +142,7 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
} }
ResultSet rs = insert.getResultSet(); ResultSet rs = insert.getResultSet();
try { try {
return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() ); return IdentifierGeneratorHelper.getGeneratedIdentity( rs, persister.getIdentifierType() );
} }
finally { finally {
rs.close(); rs.close();
@ -184,7 +184,7 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
SessionImplementor session, SessionImplementor session,
ResultSet rs, ResultSet rs,
Object object) throws SQLException { Object object) throws SQLException {
return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() ); return IdentifierGeneratorHelper.getGeneratedIdentity( rs, persister.getIdentifierType() );
} }
} }

View File

@ -67,7 +67,7 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
if (sql!=null) { if (sql!=null) {
getNext( session ); getNext( session );
} }
return IdentifierGeneratorFactory.createNumber(next++, returnClass); return IdentifierGeneratorHelper.createNumber(next++, returnClass);
} }
public void configure(Type type, Properties params, Dialect dialect) public void configure(Type type, Properties params, Dialect dialect)

View File

@ -209,7 +209,7 @@ public class MultipleHiLoPerTableGenerator
//keep the behavior consistent even for boundary usages //keep the behavior consistent even for boundary usages
int val = ( (Integer) doWorkInNewTransaction(session) ).intValue(); int val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
if (val == 0) val = ( (Integer) doWorkInNewTransaction(session) ).intValue(); if (val == 0) val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
return IdentifierGeneratorFactory.createNumber( val, returnClass ); return IdentifierGeneratorHelper.createNumber( val, returnClass );
} }
if (lo>maxLo) { if (lo>maxLo) {
int hival = ( (Integer) doWorkInNewTransaction(session) ).intValue(); int hival = ( (Integer) doWorkInNewTransaction(session) ).intValue();
@ -217,7 +217,7 @@ public class MultipleHiLoPerTableGenerator
hi = hival * (maxLo+1); hi = hival * (maxLo+1);
log.debug("new hi value: " + hival); log.debug("new hi value: " + hival);
} }
return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass ); return IdentifierGeneratorHelper.createNumber( hi + lo++, returnClass );
} }
public void configure(Type type, Properties params, Dialect dialect) throws MappingException { public void configure(Type type, Properties params, Dialect dialect) throws MappingException {

View File

@ -98,7 +98,7 @@ public class SequenceGenerator implements PersistentIdentifierGenerator, Configu
ResultSet rs = st.executeQuery(); ResultSet rs = st.executeQuery();
try { try {
rs.next(); rs.next();
Serializable result = IdentifierGeneratorFactory.get( Serializable result = IdentifierGeneratorHelper.get(
rs, identifierType rs, identifierType
); );
if ( log.isDebugEnabled() ) { if ( log.isDebugEnabled() ) {

View File

@ -75,7 +75,7 @@ public class SequenceHiLoGenerator extends SequenceGenerator {
//keep the behavior consistent even for boundary usages //keep the behavior consistent even for boundary usages
long val = ( (Number) super.generate(session, obj) ).longValue(); long val = ( (Number) super.generate(session, obj) ).longValue();
if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue(); if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
return IdentifierGeneratorFactory.createNumber( val, returnClass ); return IdentifierGeneratorHelper.createNumber( val, returnClass );
} }
if ( lo>maxLo ) { if ( lo>maxLo ) {
long hival = ( (Number) super.generate(session, obj) ).longValue(); long hival = ( (Number) super.generate(session, obj) ).longValue();
@ -85,7 +85,7 @@ public class SequenceHiLoGenerator extends SequenceGenerator {
log.debug("new hi value: " + hival); log.debug("new hi value: " + hival);
} }
return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass ); return IdentifierGeneratorHelper.createNumber( hi + lo++, returnClass );
} }
} }

View File

@ -60,7 +60,7 @@ public class SequenceIdentityGenerator extends SequenceGenerator
private static final Logger log = LoggerFactory.getLogger( SequenceIdentityGenerator.class ); private static final Logger log = LoggerFactory.getLogger( SequenceIdentityGenerator.class );
public Serializable generate(SessionImplementor s, Object obj) { public Serializable generate(SessionImplementor s, Object obj) {
return IdentifierGeneratorFactory.POST_INSERT_INDICATOR; return IdentifierGeneratorHelper.POST_INSERT_INDICATOR;
} }
public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate( public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
@ -101,7 +101,7 @@ public class SequenceIdentityGenerator extends SequenceGenerator
protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException { protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
insert.executeUpdate(); insert.executeUpdate();
return IdentifierGeneratorFactory.getGeneratedIdentity( return IdentifierGeneratorHelper.getGeneratedIdentity(
insert.getGeneratedKeys(), insert.getGeneratedKeys(),
getPersister().getIdentifierType() getPersister().getIdentifierType()
); );

View File

@ -78,7 +78,7 @@ public class TableHiLoGenerator extends TableGenerator {
//keep the behavior consistent even for boundary usages //keep the behavior consistent even for boundary usages
long val = ( (Number) super.generate(session, obj) ).longValue(); long val = ( (Number) super.generate(session, obj) ).longValue();
if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue(); if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
return IdentifierGeneratorFactory.createNumber( val, returnClass ); return IdentifierGeneratorHelper.createNumber( val, returnClass );
} }
if (lo>maxLo) { if (lo>maxLo) {
long hival = ( (Number) super.generate(session, obj) ).longValue(); long hival = ( (Number) super.generate(session, obj) ).longValue();
@ -87,7 +87,7 @@ public class TableHiLoGenerator extends TableGenerator {
log.debug("new hi value: " + hival); log.debug("new hi value: " + hival);
} }
return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass ); return IdentifierGeneratorHelper.createNumber( hi + lo++, returnClass );
} }

View File

@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.util.ReflectHelper; import org.hibernate.util.ReflectHelper;
import org.hibernate.id.IdentifierGeneratorFactory; import org.hibernate.id.IdentifierGeneratorHelper;
/** /**
* Factory for {@link Optimizer} instances. * Factory for {@link Optimizer} instances.
@ -105,7 +105,7 @@ public class OptimizerFactory {
* @return The wrapped value. * @return The wrapped value.
*/ */
protected final Serializable make(long value) { protected final Serializable make(long value) {
return IdentifierGeneratorFactory.createNumber( value, returnClass ); return IdentifierGeneratorHelper.createNumber( value, returnClass );
} }
/** /**

View File

@ -38,28 +38,6 @@ import org.hibernate.dialect.Dialect;
*/ */
public interface IdentifierGeneratorFactory { public interface IdentifierGeneratorFactory {
/**
* Marker object returned from {@link IdentifierGenerator#generate} to indicate that we should short-circuit any
* continued generated id checking. Currently this is only used in the case of the
* {@link org.hibernate.id.ForeignGenerator foreign} generator as a way to signal that we should use the associated
* entity's id value.
*/
public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() {
public String toString() {
return "SHORT_CIRCUIT_INDICATOR";
}
};
/**
* Marker object returned from {@link IdentifierGenerator#generate} to indicate that the entity's identifier will
* be generated as part of the datbase insertion.
*/
public static final Serializable POST_INSERT_INDICATOR = new Serializable() {
public String toString() {
return "POST_INSERT_INDICATOR";
}
};
/** /**
* Allow injection of the dialect to use. * Allow injection of the dialect to use.
* *

View File

@ -62,7 +62,7 @@ import org.hibernate.engine.query.HQLQueryPlan;
import org.hibernate.engine.query.NativeSQLQueryPlan; import org.hibernate.engine.query.NativeSQLQueryPlan;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification; import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
import org.hibernate.event.EventListeners; import org.hibernate.event.EventListeners;
import org.hibernate.id.IdentifierGeneratorFactory; import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.jdbc.Batcher; import org.hibernate.jdbc.Batcher;
import org.hibernate.jdbc.JDBCContext; import org.hibernate.jdbc.JDBCContext;
import org.hibernate.loader.criteria.CriteriaLoader; import org.hibernate.loader.criteria.CriteriaLoader;
@ -110,7 +110,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl
persister.setPropertyValues( entity, state, EntityMode.POJO ); persister.setPropertyValues( entity, state, EntityMode.POJO );
} }
} }
if ( id == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) { if ( id == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) {
id = persister.insert(state, entity, this); id = persister.insert(state, entity, this);
} }
else { else {