Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Copyright 2007 Daniel Spiewak
    * 
    * Licensed under the Apache License, Version 2.0 (the "License"); 
    * you may not use this file except in compliance with the License. 
    * You may obtain a copy of the License at
    * 
    *	    http://www.apache.org/licenses/LICENSE-2.0 
    * 
   * Unless required by applicable law or agreed to in writing, software 
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package net.java.ao;
  
  
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  import static net.java.ao.Common.getAttributeTypeFromMethod;
  import static net.java.ao.Common.preloadValue;
  import static net.java.ao.Common.where;
  import static net.java.ao.sql.SqlUtils.closeQuietly;

Author(s):
Daniel Spiewak
  
  public class EntityProxy<T extends RawEntity<K>, K> implements InvocationHandler
  {
  	private final K key;
  	private final EntityInfo<T, K> entityInfo;
  
  	private final EntityManager manager;
  
      private final Map<StringObjectvalues = new HashMap<StringObject>();
      private final Set<Stringdirty = new HashSet<String>();
      private final Lock lockValuesDirty = new ReentrantLock();
  
  
  	EntityProxy(EntityManager managerEntityInfo<T, K> entityInfo, K key) {
  		this. = key;
  		this. = entityInfo;
  		this. = manager;
  		
  	}
  
      {
          return .getNameConverters().getFieldNameConverter();
      }
  
      @SuppressWarnings("unchecked")
  	public Object invoke(final Object proxyfinal Method methodfinal Object[] argsthrows Throwable {
          final String methodName = method.getName();
  
          if(methodName.equals("getEntityProxy")) {
              return this;
          }
  
  		if (methodName.equals("getEntityType")) {
  			return getType();
  		}
  
  		if ( == null) {
  			.init((T) proxy);
  		}
  
  		final MethodImplWrapper methodImpl = .getMethod(methodNamemethod.getParameterTypes());
 		if (methodImpl != null) {
 			final Class<?> declaringClass = methodImpl.getMethod().getDeclaringClass();
 			if (!Object.class.equals(declaringClass)) {
                 // We don't want to return get the class Class using Class.forName as this doesn't play well
                 // with multiple ClassLoaders (if the AO library has a separate class loader to the AO client)
                 // Instead just compare the classNames
 				final String callingClassName = Common.getCallingClassName(1);
 				if (callingClassName == null || !callingClassName.equals(declaringClass.getName())) {
 					return methodImpl.getMethod().invoke(methodImpl.getInstance(), args);
 				}
 			}
 		}
 
 			return getKey();
 		}
         if (methodName.equals("save")) {
 			save((RawEntity<K>) proxy);
 			return .;
 		}
         if (methodName.equals("getEntityManager")) {
             return ;
         }
         if (methodName.equals("addPropertyChangeListener")) {
 			return null;
 		}
         if (methodName.equals("removePropertyChangeListener")) {
 			return null;
 		}
         if (methodName.equals("hashCode")) {
 			return hashCodeImpl();
 		}
         if (methodName.equals("equals")) {
 			return equalsImpl((RawEntity<K>) proxyargs[0]);
 		}
         if (methodName.equals("toString")) {
 			return toStringImpl();
 		}
         if (methodName.equals("init")) {
 			return null;
 		}
 
         final FieldInfo fieldInfo = .getField(method);
 
         if (fieldInfo != null && !fieldInfo.isNullable() && args != null && args.length > 0) {
             if (args[0] == null) {
                 throw new IllegalArgumentException("Field '" + getFieldNameConverter().getName(method) + "' does not accept null values");
             }
         }
 
         // TODO move this information into EntityInfo and friends
         final OneToOne oneToOneAnnotation = method.getAnnotation(OneToOne.class);
         final boolean isOneToOne = oneToOneAnnotation != null && RawEntity.class.isAssignableFrom(method.getReturnType());
         final OneToMany oneToManyAnnotation = method.getAnnotation(OneToMany.class);
         final boolean isOneToMany = oneToManyAnnotation != null && method.getReturnType().isArray() && RawEntity.class.isAssignableFrom(method.getReturnType().getComponentType());
         final ManyToMany manyToManyAnnotation = method.getAnnotation(ManyToMany.class);
         final boolean isManyToMany = manyToManyAnnotation != null && method.getReturnType().isArray() && RawEntity.class.isAssignableFrom(method.getReturnType().getComponentType());
         if (isOneToOne || isOneToMany || isManyToMany) {
             final Object ret;
             .lock();
             try {
                 if (.containsKey(methodName)) {
                     ret = .get(methodName);
                 } else if (isOneToOne) {
                     if (oneToOneAnnotation.reverse().isEmpty()) {
                         ret = legacyFetchOneToOne((RawEntity<K>) proxymethodoneToOneAnnotation);
                     } else {
                         ret = fetchOneToOne(methodoneToOneAnnotation);
                     }
                     .put(methodNameret);
                 } else if (isOneToMany) {
                     if (oneToManyAnnotation.reverse().isEmpty()) {
                         ret = legacyFetchOneToMany((RawEntity<K>) proxymethodoneToManyAnnotation);
                     } else {
                         ret = fetchOneToMany(methodoneToManyAnnotation);
                     }
                     .put(methodNameret);
                 } else if (isManyToMany) {
                     if (manyToManyAnnotation.reverse().isEmpty() || manyToManyAnnotation.through().isEmpty()) {
                         ret = legacyFetchManyToMany((RawEntity<K>) proxymethodmanyToManyAnnotation);
                     } else {
                         ret = fetchManyToMany(methodmanyToManyAnnotation);
                     }
                     .put(methodNameret);
                 } else {
                     ret = null;
                 }
             } finally {
                 .unlock();
             }
             return ret;
         }
 
         if (fieldInfo != null) {
 
             if (method.equals(fieldInfo.getAccessor())) {
                 return invokeGetter(fieldInfo);
             }
 
             if (method.equals(fieldInfo.getMutator())) {
                 invokeSetter(getFieldNameConverter().getName(method), args[0], fieldInfo.getPolymorphicName());
                 return .;
             }
         }
 
 		throw new IllegalArgumentException("Cannot handle method. It is not a valid getter or setter and does not have an implementation supplied. " +
                 "Signature: " + method.toString());
 	}
 
     private RawEntity[] fetchManyToMany(final Method methodfinal ManyToMany annotationthrows SQLExceptionNoSuchMethodException
     {
         final Class remoteType = method.getReturnType().getComponentType();
         final Class throughType = annotation.value();
         final String whereClause = Common.where(annotationgetFieldNameConverter());
         final Preload preloadAnnotation = (PreloadremoteType.getAnnotation(Preload.class);
         final Method reverseMethod = throughType.getMethod(annotation.reverse());
         final Method throughMethod = throughType.getMethod(annotation.through());
         final String reversePolymorphicTypeFieldName = getAttributeTypeFromMethod(reverseMethod).isAnnotationPresent(Polymorphic.class) ? getFieldNameConverter().getPolyTypeName(reverseMethod) : null;
         final String remotePolymorphicTypeFieldName = getAttributeTypeFromMethod(throughMethod).isAnnotationPresent(Polymorphic.class) ? getFieldNameConverter().getPolyTypeName(throughMethod) : null;
         final String returnField = getFieldNameConverter().getName(throughMethod);
         final Set<StringselectFields = new LinkedHashSet<String>();
         final DatabaseProvider provider = .getProvider();
         final StringBuilder sql = new StringBuilder("SELECT t.").append(provider.processID(returnField));
 
         if (remotePolymorphicTypeFieldName != null) {
             sql.append(", t.").append(provider.processID(remotePolymorphicTypeFieldName));
         } else {
             if (preloadAnnotation != null) {
                 selectFields.addAll(preloadValue(preloadAnnotationgetFieldNameConverter()));
             } else {
                 selectFields.addAll(Common.getValueFieldsNames(.resolveEntityInfo(remoteType), getFieldNameConverter()));
             }
             if (selectFields.contains(.)) {
                 sql.append(", r.*");
             } else {
                 for (final String field : selectFields) {
                     sql.append(", r.").append(.getProvider().processID(field));
                 }
             }
         }
 
         final String throughTable = provider.withSchema(getTableNameConverter().getName(throughType));
         sql.append(" FROM ").append(throughTable).append(" t ");
         final String remotePrimaryKeyField = Common.getPrimaryKeyField(remoteTypegetFieldNameConverter());
         if (!selectFields.isEmpty()) {
             final String remoteTable = provider.withSchema(getTableNameConverter().getName(remoteType));
             sql.append(" INNER JOIN ").append(remoteTable).append(" r ON t.").append(provider.processID(returnField)).append(" = r.").append(provider.processID(remotePrimaryKeyField));
         }
         final String reverseField = provider.processID(getFieldNameConverter().getName(reverseMethod));
         sql.append(" WHERE ");
         if (!selectFields.isEmpty()) {
             sql.append("t.");
         }
         sql.append(reverseField).append(" = ?");
         if (reversePolymorphicTypeFieldName != null)
         {
             sql.append(" AND ");
             if (!selectFields.isEmpty()) {
                 sql.append("t.");
             }
             sql.append(provider.processID(reversePolymorphicTypeFieldName)).append(" = ?");
         }
         if (!whereClause.trim().equals(""))
         {
             sql.append(" AND (").append(provider.processWhereClause(whereClause)).append(")");
         }
         final List<RawEntityback = new ArrayList<RawEntity>();
         final Connection conn = provider.getConnection();
         try
         {
             final PreparedStatement stmt = provider.preparedStatement(connsql);
             try
             {
                 final TypeInfo<K> dbType = getTypeManager().getType(getClass());
                 dbType.getLogicalType().putToDatabase(stmt, 1, dbType.getJdbcWriteType());
                 if (reversePolymorphicTypeFieldName != null)
                 {
                     stmt.setString(2, .getPolymorphicTypeMapper().convert(.getEntityType()));
                 }
                 final TypeInfo<K> primaryKeyType = Common.getPrimaryKeyType(provider.getTypeManager(), (Class<? extends RawEntity<K>>) remoteType);
                 final ResultSet res = stmt.executeQuery();
                 try
                 {
                     while (res.next())
                     {
                         EntityInfo entityInfo = .resolveEntityInfo((remotePolymorphicTypeFieldName == null ? remoteType : .getPolymorphicTypeMapper().invert(remoteTyperes.getString(remotePolymorphicTypeFieldName))));
                         if (selectFields.remove(.))
                         {
                             selectFields.addAll(entityInfo.getFieldNames());
                         }
                         final RawEntity returnValueEntity = .peer(entityInfoprimaryKeyType.getLogicalType().pullFromDatabase(resthroughTypereturnField));
                         final EntityProxy<?, ?> proxy = .getProxyForEntity(returnValueEntity);
                         proxy.lockValuesDirty.lock();
                         try
                         {
                             for (final String field : selectFields)
                             {
                                 proxy.values.put(fieldres.getObject(field));
                             }
                         }
                         finally
                         {
                             proxy.lockValuesDirty.unlock();
                         }
                         back.add(returnValueEntity);
                     }
                 }
                 finally
                 {
                     res.close();
                 }
             }
             finally
             {
                 stmt.close();
             }
         }
         finally
         {
             conn.close();
         }
         return back.toArray((RawEntity[]) Array.newInstance(remoteTypeback.size()));
     }
 
     private RawEntity[] fetchOneToMany(final Method methodfinal OneToMany annotationthrows SQLExceptionNoSuchMethodException
     {
         final Class remoteType = method.getReturnType().getComponentType();
         final EntityInfo entityInfo = .resolveEntityInfo(remoteType);
         final String remotePrimaryKeyFieldName = Common.getPrimaryKeyField(remoteTypegetFieldNameConverter());
         final String whereClause = where(annotationgetFieldNameConverter());
         final Preload preloadAnnotation = (PreloadremoteType.getAnnotation(Preload.class);
         final Method remoteMethod = remoteType.getMethod(annotation.reverse());
         final String remotePolymorphicTypeFieldName = getPolymorphicTypeFieldName(remoteMethod);
         final StringBuilder sql = new StringBuilder("SELECT ");
         final Set<StringselectFields = new LinkedHashSet<String>();
 
         selectFields.add(remotePrimaryKeyFieldName);
         if (remotePolymorphicTypeFieldName == null) {
             if (preloadAnnotation != null) {
                 selectFields.addAll(preloadValue(preloadAnnotationgetFieldNameConverter()));
             } else {
                 selectFields.addAll(Common.getValueFieldsNames(entityInfogetFieldNameConverter()));
             }
         }
         if (selectFields.contains(.)) {
             sql.append(.);
         } else {
             for (final String field : selectFields) {
                 sql.append(.getProvider().processID(field)).append(',');
             }
             sql.setLength(sql.length() - 1);
         }
 
         sql.append(" FROM ").append(.getProvider().withSchema(getTableNameConverter().getName(remoteType)));
         sql.append(" WHERE ").append(.getProvider().processID(getFieldNameConverter().getName(remoteMethod))).append(" = ?");
         if (!whereClause.trim().equals("")) {
             sql.append(" AND (").append(.getProvider().processWhereClause(whereClause)).append(")");
         }
         if (remotePolymorphicTypeFieldName != null) {
             sql.append(" AND ").append(.getProvider().processID(remotePolymorphicTypeFieldName)).append(" = ?");
         }
         final Connection conn = .getProvider().getConnection();
         try {
             final PreparedStatement stmt = .getProvider().preparedStatement(connsql);
             try
             {
                 final TypeInfo<K> dbType = getTypeManager().getType(getClass());
                 dbType.getLogicalType().putToDatabase(stmt, 1, dbType.getJdbcWriteType());
                 if (remotePolymorphicTypeFieldName != null) {
                     stmt.setString(2, .getPolymorphicTypeMapper().convert(entityInfo.getEntityType()));
                 }
                 final ResultSet res = stmt.executeQuery();
                 try {
                     final List<RawEntity<?>> result = new ArrayList<RawEntity<?>>();
                     while (res.next()) {
                         final Object returnValue = Common.getPrimaryKeyType(getTypeManager(), (ClassremoteType).getLogicalType().pullFromDatabase(res, (ClassremoteTyperemotePrimaryKeyFieldName);
                         final RawEntity<?> returnValueEntity = .peer(entityInforeturnValue);
                         final EntityProxy<?, ?> proxy = .getProxyForEntity(returnValueEntity);
                         if (selectFields.remove(.))
                         {
                             selectFields.addAll(entityInfo.getFieldNames());
                         }
                         proxy.lockValuesDirty.lock();
                         try {
                             for (final String field : selectFields) {
                                 proxy.values.put(fieldres.getObject(field));
                             }
                         } finally {
                             proxy.lockValuesDirty.unlock();
                         }
                         result.add(returnValueEntity);
                     }
                     return result.toArray((RawEntity<?>[]) Array.newInstance(remoteTyperesult.size()));
                 } finally {
                     res.close();
                 }
             } finally {
                 stmt.close();
             }
         } finally {
             conn.close();
         }
     }
 
     private String getPolymorphicTypeFieldName(final Method remoteMethod)
     {
         final Class<?> attributeType = getAttributeTypeFromMethod(remoteMethod);
         return attributeType != null && attributeType.isAssignableFrom(getType())
                 && attributeType.isAnnotationPresent(Polymorphic.class) ? getFieldNameConverter().getPolyTypeName(remoteMethod) : null;
     }
 
     private RawEntity fetchOneToOne(final Method methodfinal OneToOne annotationthrows SQLExceptionNoSuchMethodException
     {
         final Class remoteType = method.getReturnType();
         final EntityInfo entityInfo = .resolveEntityInfo(remoteType);
         final String remotePrimaryKeyFieldName = Common.getPrimaryKeyField(remoteTypegetFieldNameConverter());
         final String whereClause = Common.where(annotationgetFieldNameConverter());
         final Method remoteMethod = remoteType.getMethod(annotation.reverse());
         final String remotePolymorphicTypeFieldName = getPolymorphicTypeFieldName(remoteMethod);
         final Preload preloadAnnotation = (PreloadremoteType.getAnnotation(Preload.class);
         final StringBuilder sql = new StringBuilder("SELECT ");
         final Set<StringselectFields = new LinkedHashSet<String>();
 
         selectFields.add(remotePrimaryKeyFieldName);
         if (remotePolymorphicTypeFieldName == null) {
             if (preloadAnnotation != null) {
                 selectFields.addAll(preloadValue(preloadAnnotationgetFieldNameConverter()));
             } else {
                 selectFields.addAll(Common.getValueFieldsNames(entityInfogetFieldNameConverter()));
             }
         }
         if (selectFields.contains(.)) {
             sql.append(.);
         } else {
             for (final String field : selectFields) {
                 sql.append(.getProvider().processID(field)).append(',');
             }
             sql.setLength(sql.length() - 1);
         }
 
         sql.append(" FROM ").append(.getProvider().withSchema(getTableNameConverter().getName(remoteType)));
         sql.append(" WHERE ").append(.getProvider().processID(getFieldNameConverter().getName(remoteMethod))).append(" = ?");
         if (whereClause.trim().length() != 0)
         {
             sql.append(" AND (").append(.getProvider().processWhereClause(whereClause)).append(")");
         }
         if (remotePolymorphicTypeFieldName != null)
         {
             sql.append(" AND ").append(.getProvider().processID(remotePolymorphicTypeFieldName)).append(" = ?");
         }
         final Connection conn = .getProvider().getConnection();
         try
         {
             final PreparedStatement stmt = .getProvider().preparedStatement(connsql);
             try
             {
                 final TypeInfo<K> dbType = getTypeManager().getType(getClass());
                 dbType.getLogicalType().putToDatabase(stmt, 1, dbType.getJdbcWriteType());
                 if (remotePolymorphicTypeFieldName != null)
                 {
                     stmt.setString(2, .getPolymorphicTypeMapper().convert(entityInfo.getEntityType()));
                 }
                 final ResultSet res = stmt.executeQuery();
                 try
                 {
                     if (res.next())
                     {
                         final RawEntity returnValueEntity = .peer(entityInfo, Common.getPrimaryKeyType(getTypeManager(), (Class<? extends RawEntity<K>>) remoteType).getLogicalType().pullFromDatabase(res, (Class<K>) remoteTyperemotePrimaryKeyFieldName));
                         if (selectFields.remove(.))
                         {
                             selectFields.addAll(entityInfo.getFieldNames());
                         }
                         final EntityProxy<?, ?> proxy = .getProxyForEntity(returnValueEntity);
                         proxy.lockValuesDirty.lock();
                         try
                         {
                             for (final String field : selectFields)
                             {
                                 proxy.values.put(fieldres.getObject(field));
                             }
                         }
                         finally
                         {
                             proxy.lockValuesDirty.unlock();
                         }
                         return returnValueEntity;
                     }
                     else
                     {
                         return null;
                     }
                 }
                 finally
                 {
                     res.close();
                 }
             }
             finally
             {
                 stmt.close();
             }
         }
         finally
         {
             conn.close();
         }
     }

    

See also:
AO-325
 
     @Deprecated
     private RawEntity[] legacyFetchManyToMany(final RawEntity<K> proxyfinal Method methodfinal ManyToMany manyToManyAnnotationthrows SQLException
     {
         final Class<? extends RawEntity<?>> throughType = manyToManyAnnotation.value();
         final Class<? extends RawEntity<?>> type = (Class<? extends RawEntity<?>>) method.getReturnType().getComponentType();
         return retrieveRelations(proxynull,
                 Common.getMappingFields(getFieldNameConverter(),
                         throughTypetype), throughType, (Class<? extends RawEntity>) type,
                         Common.where(manyToManyAnnotationgetFieldNameConverter()),
                         Common.getPolymorphicFieldNames(getFieldNameConverter(), throughType.getEntityType()),
                         Common.getPolymorphicFieldNames(getFieldNameConverter(), throughTypetype));
     }

    

See also:
AO-325
 
     @Deprecated
     private RawEntity[] legacyFetchOneToMany(final RawEntity<K> proxyfinal Method methodfinal OneToMany oneToManyAnnotationthrows SQLException
     {
         final Class<? extends RawEntity<?>> type = (Class<? extends RawEntity<?>>) method.getReturnType().getComponentType();
         return retrieveRelations(proxynew String[0],
                 new String[] { Common.getPrimaryKeyField(typegetFieldNameConverter()) },
                 (Class<? extends RawEntity>) typewhere(oneToManyAnnotationgetFieldNameConverter()),
                 Common.getPolymorphicFieldNames(getFieldNameConverter(), type.getEntityType()));
     }

    

See also:
AO-325
 
     @Deprecated
     private RawEntity legacyFetchOneToOne(final RawEntity<K> proxyfinal Method methodfinal OneToOne oneToOneAnnotationthrows SQLException
     {
         Class<? extends RawEntity<?>> type = (Class<? extends RawEntity<?>>) method.getReturnType();
         final RawEntity[] back = retrieveRelations(proxynew String[0],
                 new String[] { Common.getPrimaryKeyField(typegetFieldNameConverter()) },
                 (Class<? extends RawEntity>) type, Common.where(oneToOneAnnotationgetFieldNameConverter()),
                 Common.getPolymorphicFieldNames(getFieldNameConverter(), type.getEntityType()));
         return back.length == 0 ? null : back[0];
     }
 
     {
         return .getNameConverters().getTableNameConverter();
     }
 
     public K getKey() {
 		return ;
 	}
 
 	@SuppressWarnings("unchecked")
 	public void save(RawEntity entitythrows SQLException {
         .lock();
         try {
             if (.isEmpty()) {
                 return;
             }
 
             String table = .getName();
             final DatabaseProvider provider = this..getProvider();
             final TypeManager typeManager = provider.getTypeManager();
             Connection conn = null;
             PreparedStatement stmt = null;
             try
             {
                 conn = provider.getConnection();
                 StringBuilder sql = new StringBuilder("UPDATE " + provider.withSchema(table) + " SET ");
 
                 for (String name : ) {
                     sql.append(provider.processID(name));
 
                     if (.containsKey(name)) {
                         sql.append(" = ?,");
                     } else {
                         sql.append(" = NULL,");
                     }
                 }
 
                 if (sql.charAt(sql.length() - 1) == ',') {
                     sql.setLength(sql.length() - 1);
                 }
 
                 sql.append(" WHERE ").append(provider.processID(.getPrimaryKey().getName())).append(" = ?");
 
                 stmt = provider.preparedStatement(connsql);
 
                 List<PropertyChangeEventevents = new LinkedList<PropertyChangeEvent>();
                 int index = 1;
                 for (String name : ) {
                     if (!.containsKey(name)) {
                         continue;
                     }
 
                     Object value = .get(name);
                     FieldInfo fieldInfo = .getField(name);
 
                     events.add(new PropertyChangeEvent(entitynamenullvalue));
 
                     if (value == null) {
                         this..getProvider().putNull(stmtindex++);
                     } else {
                         Class javaType = value.getClass();
 
                         if (value instanceof RawEntity) {
                             javaType = ((RawEntityvalue).getEntityType();
                         }
 
                         TypeInfo dbType = typeManager.getType(javaType);
                         dbType.getLogicalType().validate(value);
                         dbType.getLogicalType().putToDatabase(this.stmtindex++, valuedbType.getJdbcWriteType());
 
                         if (!fieldInfo.isStorable()) {
                             .remove(name);
                         }
                     }
                 }
                 TypeInfo pkType = .getPrimaryKey().getTypeInfo();
                 pkType.getLogicalType().putToDatabase(this.stmtindexpkType.getJdbcWriteType());
                 stmt.executeUpdate();
                 .clear();
 
                 for (PropertyChangeListener l : ) {
                     for (PropertyChangeEvent evt : events) {
                         l.propertyChange(evt);
                     }
                 }
             }
             finally
             {
                 closeQuietly(stmt);
                 closeQuietly(conn);
             }
         } finally {
             .unlock();
         }
     }
 
 		.add(listener);
 	}
 
 		.remove(listener);
 	}
 
 	public int hashCodeImpl() {
 		return (.hashCode() + .hashCode()) % (2 << 15);
 	}
 
 	public boolean equalsImpl(RawEntity<K> proxyObject obj) {
 		if (proxy == obj) {
 			return true;
 		}
 
 		if (obj instanceof RawEntity<?>) {
 			RawEntity<?> entity = (RawEntity<?>) obj;
 
             String ourTableName = getTableNameConverter().getName(proxy.getEntityType());
             String theirTableName = getTableNameConverter().getName(entity.getEntityType());
 
 			return Common.getPrimaryKeyValue(entity).equals() && theirTableName.equals(ourTableName);
 		}
 
 		return false;
 	}
 
 	public String toStringImpl() {
         return .getName() + " {" + .getPrimaryKey().getName() + " = " + .toString() + "}";
 	}
 
 	public boolean equals(Object obj) {
 		if (obj == this) {
 			return true;
 		}
 
 		if (obj instanceof EntityProxy<?, ?>) {
 			EntityProxy<?, ?> proxy = (EntityProxy<?, ?>) obj;
 
 			if (proxy.entityInfo.equals() && proxy.key.equals()) {
 				return true;
 			}
 		}
 
 		return false;
 	}
 
 	public int hashCode() {
 		return hashCodeImpl();
 	}

    
Thread safely update the values with those provided. This is only used by EntityManager.find(java.lang.Class,java.lang.String,net.java.ao.Query), which should really move the leave the population of this class to itself.

Parameters:
updatedValues mandatory
 
     protected void updateValues(Map<StringObjectupdatedValues) {
         .lock();
         try {
             for (Map.Entry<StringObjectupdatedValue : updatedValues.entrySet()) {
                 .put(updatedValue.getKey(), updatedValue.getValue());
             }
         } finally {
             .unlock();
         }
     }
 
 	Class<T> getType() {
 	}
 
     private <V> V invokeGetter(FieldInfo<V> fieldInfothrows Throwable {
         final Class<V> type = fieldInfo.getJavaType();
         final String name = fieldInfo.getName();
         final boolean isStorable = fieldInfo.isStorable();
 
         .lock();
         try {
             if (.containsKey(name) && isStorable) {
                 Object value = .get(name);
                 if (instanceOf(valuetype)) {
                     //noinspection unchecked
                     return handleNullReturn((V) valuetype);
                 } else if (isBigDecimal(valuetype)) { // Oracle for example returns BigDecimal when we expect doubles
                     //noinspection unchecked
                     return (V) handleBigDecimal(valuetype);
                 } else if (RawEntity.class.isAssignableFrom(type)) {
                     //noinspection unchecked
                     EntityInfo<? extends RawEntityObjectremoteEntityInfo = .resolveEntityInfo((Class<? extends RawEntity>) type);
                     if (instanceOf(valueremoteEntityInfo.getPrimaryKey().getJavaType())) {
                         value = .peer(remoteEntityInfovalue);
 
                         .put(namevalue);
                         //noinspection unchecked
                         return handleNullReturn((V) valuetype);
                     }
                 }
             }
 
             final V back = pullFromDatabase(fieldInfo);
 
             if (isStorable) {
                 .put(nameback);
             }
 
             return handleNullReturn(backtype);
         } finally {
             .unlock();
         }
     }
 
     private <V> V pullFromDatabase(FieldInfo<V> fieldInfothrows SQLException {
         Class<V> type = fieldInfo.getJavaType();
         String name = fieldInfo.getName();
         final DatabaseProvider provider = .getProvider();
         Connection conn = null;
         PreparedStatement stmt = null;
         ResultSet res = null;
         V back = null;
         try {
             conn = provider.getConnection();
             StringBuilder sql = new StringBuilder("SELECT ");
 
             sql.append(provider.processID(name));
             String polyName = fieldInfo.getPolymorphicName();
             if (polyName != null) {
                 sql.append(',').append(provider.processID(polyName));
             }
 
             sql.append(" FROM ").append(provider.withSchema(.getName())).append(" WHERE ");
             sql.append(provider.processID(.getPrimaryKey().getName())).append(" = ?");
 
             stmt = provider.preparedStatement(connsql);
             TypeInfo<K> pkType = .getPrimaryKey().getTypeInfo();
             pkType.getLogicalType().putToDatabase(stmt, 1, getKey(), pkType.getJdbcWriteType());
 
             res = stmt.executeQuery();
             if (res.next()) {
                 back = convertValue(resprovider.shorten(name), provider.shorten(polyName), type);
             }
         } finally {
             closeQuietly(resstmtconn);
         }
         return back;
     }
 
     private <V> V handleNullReturn(V backClass<V> type) {
         return back != null ? back : Defaults.defaultValue(type);
 	}
 
     private void invokeSetter(String nameObject valueString polyNamethrows Throwable {
         .lock();
         try {
             .put(namevalue);
             .add(name);
 
             if (polyName != null) {
                 String strValue = null;
 
                 if (value != null) {
                     strValue = .getPolymorphicTypeMapper().convert(((RawEntity<?>) value).getEntityType());
                 }
 
                 .put(polyNamestrValue);
                 .add(polyName);
             }
         } finally {
             .unlock();
         }
     }

    

See also:
AO-325
 
     @Deprecated
     private <V extends RawEntity<K>> V[] retrieveRelations(RawEntity<K> entityString[] inMapFields,
 			String[] outMapFieldsClass<V> typeString whereString[] thisPolyNamesthrows SQLException {
 		return retrieveRelations(entityinMapFieldsoutMapFieldstypetypewherethisPolyNamesnull);
 	}

    

See also:
AO-325
 
     @Deprecated
     private <V extends RawEntity<K>> V[] retrieveRelations(final RawEntity<K> entity,
                                                            String[] inMapFields,
                                                            final String[] outMapFields,
                                                            final Class<? extends RawEntity<?>> type,
                                                            final Class<V> finalType,
                                                            final String where,
                                                            final String[] thisPolyNames,
                                                            final String[] thatPolyNamesthrows SQLException
     {
 		if (inMapFields == null || inMapFields.length == 0) {
             inMapFields = Common.getMappingFields(getFieldNameConverter(), type.getEntityType());
 		}
 		List<V> back = new ArrayList<V>();
 		List<StringresPolyNames = new ArrayList<String>(thatPolyNames == null ? 0 : thatPolyNames.length);
 
         String table = getTableNameConverter().getName(type);
 		boolean oneToMany = type.equals(finalType);
 		final Preload preloadAnnotation = finalType.getAnnotation(Preload.class);
 
         final DatabaseProvider provider = .getProvider();
         Connection conn = null;
         PreparedStatement stmt = null;
         ResultSet res = null;
 		try {
             conn = provider.getConnection();
 			StringBuilder sql = new StringBuilder();
 			String returnField;
 			String throughField;
 			int numParams = 0;
 			
 			Set<StringselectFields = new LinkedHashSet<String>();
 			
 			if (oneToMany && inMapFields.length == 1 && outMapFields.length == 1 && (thatPolyNames == null || thatPolyNames.length == 0)) {
                 // one-to-one, one-to-many non polymorphic relation
 				sql.append("SELECT ");
 				
 				selectFields.add(outMapFields[0]);
                 if (preloadAnnotation != null) {
                     selectFields.addAll(preloadValue(preloadAnnotationgetFieldNameConverter()));
                 } else {
                     selectFields.addAll(Common.getValueFieldsNames(.resolveEntityInfo(finalType), getFieldNameConverter()));
                 }
 
 				if (selectFields.contains(.)) {
 				} else {
 					for (String field : selectFields) {
 						sql.append(provider.processID(field)).append(',');
 					}
 					sql.setLength(sql.length() - 1);
 				}
 				
 				sql.append(" FROM ").append(provider.withSchema(table));
 				
 				sql.append(" WHERE ").append(provider.processID(inMapFields[0])).append(" = ?");
 				
 				if (!where.trim().equals("")) {
                     sql.append(" AND (").append(.getProvider().processWhereClause(where)).append(")");
 				}
 				
 				if (thisPolyNames != null) {
 					for (String name : thisPolyNames) {
 						sql.append(" AND ").append(provider.processID(name)).append(" = ?");
 					}
 				}
 				
 				numParams++;
 				returnField = outMapFields[0];
 			}
             else if (!oneToMany && inMapFields.length == 1 && outMapFields.length == 1 && (thatPolyNames == null || thatPolyNames.length == 0)) {
                 // many-to-many non polymorphic relation
                 final String finalTable = getTableNameConverter().getName(finalType);
                 final String finalTableAlias = "f";
                 final String tableAlias = "t";
 
                 returnField = .getProvider().shorten(finalTable + "__aointernal__id");
                 throughField = .getProvider().shorten(table + "__aointernal__id");
 
 				sql.append("SELECT ");
 
                 String finalPKField = Common.getPrimaryKeyField(finalTypegetFieldNameConverter());
 
 				selectFields.add(finalPKField);
                 if (preloadAnnotation != null) {
 				    selectFields.addAll(preloadValue(preloadAnnotationgetFieldNameConverter()));
                 } else {
                     selectFields.addAll(Common.getValueFieldsNames(.resolveEntityInfo(finalType), getFieldNameConverter()));
                 }
 
                 if (selectFields.contains(.)) {
                     selectFields.remove(.);
                     selectFields.addAll(Common.getValueFieldsNames(.resolveEntityInfo(finalType), getFieldNameConverter()));
                 }
 
                 sql.append(finalTableAlias).append('.').append(provider.processID(finalPKField));
                 sql.append(" AS ").append(provider.quote(returnField)).append(',');
 
                 selectFields.remove(finalPKField);
 
                 sql.append(tableAlias).append('.').append(provider.processID(Common.getPrimaryKeyField(typegetFieldNameConverter())));
 				sql.append(" AS ").append(provider.quote(throughField)).append(',');
 
 				for (String field : selectFields) {
 					sql.append(finalTableAlias).append('.').append(provider.processID(field)).append(',');
 				}
 				sql.setLength(sql.