加入对复合ID(嵌入式)的提取不起作用

时间:2014-03-27 12:10:41

标签: hibernate jpa

复合ID的@ManyToOne的Hibernate提取失败,存在的理由是 在重新加载emded ID期间,实体直接从DB加载,而不是从resultSet加载,甚至从会话缓存加载。

protected final Object resolveIdentifier(Serializable id, SessionImplementor session) throws HibernateException {
        EntityPersister entityPersister = session.getFactory()
        .getEntityPersister( getAssociatedEntityName() );
        boolean isProxyUnwrapEnabled = unwrapProxy &&
                entityPersister.isInstrumented( session.getEntityMode() );      
            proxyOrEntity = loader.instanceNotYetLoaded(rs, i, persisters[i], descriptors[i].getRowIdAlias(), 
                            entityKey, lockModes[i], null, null, hydratedObjects, session);
                    return proxyOrEntity;
                }                           
            }
        } catch (Exception e) {
            throw new HibernateException(e);
        } 

结果就是如果你加载了100个其他Entites的复合ID的Entity记录,你将得到:1 + 2 * 100 Queries!

1 个答案:

答案 0 :(得分:0)

   org.hibernate.type.EntityType

   protected final Object resolveIdentifier(Serializable id, SessionImplementor session) throws HibernateException {
        EntityPersister entityPersister = session.getFactory()
                        .getEntityPersister( getAssociatedEntityName() );
        boolean isProxyUnwrapEnabled = unwrapProxy &&
                                entityPersister.isInstrumented( session.getEntityMode() );      
        /**** first check the session cache *****/
        EntityKey entityKey = new EntityKey(id, 
                                entityPersister, session.getEntityMode() );
                    Object proxyOrEntity = session.getPersistenceContext().getEntity( entityKey );            
        if (proxyOrEntity!=null)
            return proxyOrEntity;
        /**** second check the fetchs of resultSet *****/
        try {
             if ( loader!=null && !rs.isClosed() ){         
                 final EntityAliases[] descriptors = loader.getEntityAliases_();                                    
                 String[] identifierAliases = (String[]) PrivateAccessor.getPrivateField( entityPersister, "identifierAliases", true);              
                 for (int i=0;i<descriptors.length;i++){
                    boolean founds = true;
                    for(int j=0;j<identifierAliases.length;j++){                                                       if (descriptors[i].getSuffixedKeyAliases().length!=identifierAliases.length)
                            founds = false;
                    else
                        if (!descriptors[i].getSuffixedKeyAliases()[j].toString().startsWith(identifierAliases[j]))
                        founds = false;                     
                    }       
                    if (!founds)
                     continue; 
    proxyOrEntity = loader.instanceNotYetLoaded(rs, i, persisters[i], descriptors[i].getRowIdAlias(), entityKey, lockModes[i], null, null, hydratedObjects, session);
            return proxyOrEntity;
            }                           
       }
    } catch (Exception e) {
        throw new HibernateException(e);
    }
    /***** old code *****/
        proxyOrEntity = session.internalLoad(
                getAssociatedEntityName(),
                id,
                eager,
                isNullable() && !isProxyUnwrapEnabled
            );

        if ( proxyOrEntity instanceof HibernateProxy ) {
            ( ( HibernateProxy ) proxyOrEntity ).getHibernateLazyInitializer()
                        .setUnwrap( isProxyUnwrapEnabled );
        }

    return proxyOrEntity;