|
From: <hib...@li...> - 2006-06-15 16:38:21
|
Author: ste...@jb...
Date: 2006-06-15 12:38:03 -0400 (Thu, 15 Jun 2006)
New Revision: 10020
Modified:
trunk/Hibernate3/src/org/hibernate/type/ManyToOneType.java
Log:
HHH-1831 : be careful about ManyToOneType adding entity keys to the batch fetch queue
Modified: trunk/Hibernate3/src/org/hibernate/type/ManyToOneType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/ManyToOneType.java 2006-06-15 07:50:12 UTC (rev 10019)
+++ trunk/Hibernate3/src/org/hibernate/type/ManyToOneType.java 2006-06-15 16:38:03 UTC (rev 10020)
@@ -17,104 +17,110 @@
import org.hibernate.persister.entity.EntityPersister;
/**
- * A many-to-one association to an entity
+ * A many-to-one association to an entity.
+ *
* @author Gavin King
*/
public class ManyToOneType extends EntityType {
private final boolean ignoreNotFound;
-
- protected boolean isNullable() {
- return ignoreNotFound;
- }
-
- /**
- * If we have <tt>not-found="ignore"</tt> association
- * mapped to a formula, we always need to dirty check
- * it, so we can update the second-level cache
- */
- public boolean isAlwaysDirtyChecked() {
- return ignoreNotFound;
- }
-
- public int getColumnSpan(Mapping mapping) throws MappingException {
- return getIdentifierOrUniqueKeyType(mapping).getColumnSpan(mapping);
- }
- public int[] sqlTypes(Mapping mapping) throws MappingException {
- return getIdentifierOrUniqueKeyType(mapping).sqlTypes(mapping);
+ public ManyToOneType(String className) {
+ this( className, false );
}
- public ManyToOneType(String className) {
- this(className, false);
- }
-
public ManyToOneType(String className, boolean lazy) {
- super(className, null, !lazy, true, false);
+ super( className, null, !lazy, true, false );
this.ignoreNotFound = false;
}
public ManyToOneType(
- String entityName,
+ String entityName,
String uniqueKeyPropertyName,
boolean lazy,
- boolean unwrapProxy,
+ boolean unwrapProxy,
boolean isEmbeddedInXML,
- boolean ignoreNotFound
- ) {
- super(entityName, uniqueKeyPropertyName, !lazy, isEmbeddedInXML, unwrapProxy);
+ boolean ignoreNotFound) {
+ super( entityName, uniqueKeyPropertyName, !lazy, isEmbeddedInXML, unwrapProxy );
this.ignoreNotFound = ignoreNotFound;
}
- public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session)
- throws HibernateException, SQLException {
- getIdentifierOrUniqueKeyType( session.getFactory() )
- .nullSafeSet(st, getIdentifier(value, session), index, settable, session);
+ protected boolean isNullable() {
+ return ignoreNotFound;
}
- public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
- throws HibernateException, SQLException {
- getIdentifierOrUniqueKeyType( session.getFactory() )
- .nullSafeSet(st, getIdentifier(value, session), index, session);
+ public boolean isAlwaysDirtyChecked() {
+ // If we have <tt>not-found="ignore"</tt> association mapped to a
+ // formula, we always need to dirty check it, so we can update the
+ // second-level cache
+ return ignoreNotFound;
}
public boolean isOneToOne() {
return false;
}
+
+ public int getColumnSpan(Mapping mapping) throws MappingException {
+ // our column span is the number of columns in the PK
+ return getIdentifierOrUniqueKeyType( mapping ).getColumnSpan( mapping );
+ }
+ public int[] sqlTypes(Mapping mapping) throws MappingException {
+ return getIdentifierOrUniqueKeyType( mapping ).sqlTypes( mapping );
+ }
+
+ public void nullSafeSet(
+ PreparedStatement st,
+ Object value,
+ int index,
+ boolean[] settable,
+ SessionImplementor session) throws HibernateException, SQLException {
+ getIdentifierOrUniqueKeyType( session.getFactory() )
+ .nullSafeSet( st, getIdentifier( value, session ), index, settable, session );
+ }
+
+ public void nullSafeSet(
+ PreparedStatement st,
+ Object value,
+ int index,
+ SessionImplementor session) throws HibernateException, SQLException {
+ getIdentifierOrUniqueKeyType( session.getFactory() )
+ .nullSafeSet( st, getIdentifier( value, session ), index, session );
+ }
+
public ForeignKeyDirection getForeignKeyDirection() {
return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT;
}
- public Object hydrate(ResultSet rs, String[] names, SessionImplementor session, Object owner)
- throws HibernateException, SQLException {
-
- //return the (fully resolved) identifier value, but do not resolve
- //to the actual referenced entity instance
-
+ public Object hydrate(
+ ResultSet rs,
+ String[] names,
+ SessionImplementor session,
+ Object owner) throws HibernateException, SQLException {
+ // return the (fully resolved) identifier value, but do not resolve
+ // to the actual referenced entity instance
+ // NOTE: the owner of the association is not really the owner of the id!
Serializable id = (Serializable) getIdentifierOrUniqueKeyType( session.getFactory() )
- .nullSafeGet(rs, names, session, null); //note that the owner of the association is not really the owner of the id!
-
- if (id!=null) scheduleBatchLoad(id, session);
-
+ .nullSafeGet( rs, names, session, null );
+ scheduleBatchLoadIfNeeded( id, session );
return id;
}
/**
* Register the entity as batch loadable, if enabled
*/
- private void scheduleBatchLoad(Serializable id, SessionImplementor session)
- throws MappingException {
-
- if (uniqueKeyPropertyName==null) { //cannot batch fetch by unique key
-
- EntityPersister persister = session.getFactory()
- .getEntityPersister( getAssociatedEntityName() );
-
+ private void scheduleBatchLoadIfNeeded(
+ Serializable id,
+ SessionImplementor session) throws MappingException {
+ //cannot batch fetch by unique key (property-ref associations)
+ if ( uniqueKeyPropertyName == null && id != null ) {
+ EntityPersister persister = session.getFactory().getEntityPersister( getAssociatedEntityName() );
EntityKey entityKey = new EntityKey( id, persister, session.getEntityMode() );
- session.getPersistenceContext()
- .getBatchFetchQueue()
- .addBatchLoadableEntityKey( entityKey );
+ if ( !session.getPersistenceContext().containsEntity( entityKey ) ) {
+ session.getPersistenceContext()
+ .getBatchFetchQueue()
+ .addBatchLoadableEntityKey( entityKey );
+ }
}
}
@@ -122,24 +128,33 @@
return false;
}
- public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session)
- throws HibernateException {
-
- if (current==null) return old!=null;
- if (old==null) return current!=null;
- //the ids are fully resolved, so compare them with isDirty(), not isModified()
+ public boolean isModified(
+ Object old,
+ Object current,
+ boolean[] checkable,
+ SessionImplementor session) throws HibernateException {
+ if ( current == null ) {
+ return old!=null;
+ }
+ if ( old == null ) {
+ // we already know current is not null...
+ return true;
+ }
+ // the ids are fully resolved, so compare them with isDirty(), not isModified()
return getIdentifierOrUniqueKeyType( session.getFactory() )
- .isDirty( old, getIdentifier(current, session), session );
+ .isDirty( old, getIdentifier( current, session ), session );
}
- public Serializable disassemble(Object value, SessionImplementor session, Object owner)
- throws HibernateException {
+ public Serializable disassemble(
+ Object value,
+ SessionImplementor session,
+ Object owner) throws HibernateException {
- if ( isNotEmbedded(session) ) {
- return getIdentifierType(session).disassemble(value, session, owner);
+ if ( isNotEmbedded( session ) ) {
+ return getIdentifierType( session ).disassemble( value, session, owner );
}
- if (value==null) {
+ if ( value == null ) {
return null;
}
else {
@@ -148,78 +163,84 @@
Object id = ForeignKeys.getEntityIdentifierIfNotUnsaved(
getAssociatedEntityName(),
value,
- session
- );
- if (id==null) {
+ session
+ );
+ if ( id == null ) {
throw new AssertionFailure(
"cannot cache a reference to an object with a null id: " +
- getAssociatedEntityName()
- );
+ getAssociatedEntityName()
+ );
}
- return getIdentifierType(session).disassemble(id, session, owner);
+ return getIdentifierType( session ).disassemble( id, session, owner );
}
}
- public Object assemble(Serializable oid, SessionImplementor session, Object owner)
- throws HibernateException {
+ public Object assemble(
+ Serializable oid,
+ SessionImplementor session,
+ Object owner) throws HibernateException {
//TODO: currently broken for unique-key references (does not detect
// change to unique key property of the associated object)
Serializable id = assembleId( oid, session );
- if ( isNotEmbedded(session) ) return id;
+ if ( isNotEmbedded( session ) ) {
+ return id;
+ }
- if (id==null) {
+ if ( id == null ) {
return null;
}
else {
- return resolveIdentifier(id, session);
+ return resolveIdentifier( id, session );
}
}
private Serializable assembleId(Serializable oid, SessionImplementor session) {
- return (Serializable) getIdentifierType(session)
- .assemble(oid, session, null); //the owner of the association is not the owner of the id
+ //the owner of the association is not the owner of the id
+ return ( Serializable ) getIdentifierType( session ).assemble( oid, session, null );
}
public void beforeAssemble(Serializable oid, SessionImplementor session) {
- if ( uniqueKeyPropertyName==null && oid!=null ) {
- EntityPersister persister = session.getFactory().getEntityPersister( getAssociatedEntityName() );
- EntityKey key = new EntityKey( assembleId(oid, session), persister, session.getEntityMode() );
- session.getPersistenceContext().getBatchFetchQueue().addBatchLoadableEntityKey(key);
- }
+ scheduleBatchLoadIfNeeded( assembleId( oid, session ), session );
}
public boolean[] toColumnNullness(Object value, Mapping mapping) {
- boolean[] result = new boolean[ getColumnSpan(mapping) ];
- if (value!=null) Arrays.fill(result, true);
+ boolean[] result = new boolean[ getColumnSpan( mapping ) ];
+ if ( value != null ) {
+ Arrays.fill( result, true );
+ }
return result;
}
- public boolean isDirty(Object old, Object current, SessionImplementor session)
- throws HibernateException {
-
- if ( isSame( old, current, session.getEntityMode() ) ) return false;
-
- Object oldid = getIdentifier(old, session);
- Object newid = getIdentifier(current, session);
- return getIdentifierType(session).isDirty( oldid, newid, session );
-
+ public boolean isDirty(
+ Object old,
+ Object current,
+ SessionImplementor session) throws HibernateException {
+ if ( isSame( old, current, session.getEntityMode() ) ) {
+ return false;
+ }
+ Object oldid = getIdentifier( old, session );
+ Object newid = getIdentifier( current, session );
+ return getIdentifierType( session ).isDirty( oldid, newid, session );
}
- public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session)
- throws HibernateException {
-
+ public boolean isDirty(
+ Object old,
+ Object current,
+ boolean[] checkable,
+ SessionImplementor session) throws HibernateException {
if ( isAlwaysDirtyChecked() ) {
- return isDirty(old, current, session);
+ return isDirty( old, current, session );
}
else {
- if ( isSame( old, current, session.getEntityMode() ) ) return false;
-
- Object oldid = getIdentifier(old, session);
- Object newid = getIdentifier(current, session);
- return getIdentifierType(session).isDirty( oldid, newid, checkable, session );
+ if ( isSame( old, current, session.getEntityMode() ) ) {
+ return false;
+ }
+ Object oldid = getIdentifier( old, session );
+ Object newid = getIdentifier( current, session );
+ return getIdentifierType( session ).isDirty( oldid, newid, checkable, session );
}
}
|