2011-01-26 15 views
11

elimden tembel çoğa tek ve çok sayıda bire dernek yük ama yapamam birçok çoğa derneklerle.Nasıl tembel yükleme hazırda çoktan çoğa koleksiyonu var?

Biz tüccarlar adresleri var wich sahip wich bir şehir var. Satıcıların birden fazla adresi olabilir ve birden çok satıcı aynı adreslere sahip olabilir.

bir get bir tüccarı yük

, biz onların üzerinde yineleme kadar

Merchant merchant = (Merchant) hib_session.get(Merchant.class, id); 
System.out.println(merchant.getName()); 

tamam, adresleri yük değildir.

Ama biz tüccar bir listesini yüklediğinizde

City city = (City) hib_session.get(City.class, city_name); 
for(Merchant merchant : city.getMerchants()) { 
    System.out.println(merchant.getName()); 
} 

biz adreslerini almak olmasa bile, otomatik olarak hazırda bekletme onları yükler.

Here's an example of my problem.

haritalama:

<class name="Merchant" table="Merchants" lazy="true"> 
    <id name="id" 
    type="long" 
    column="id"> 
    <generator class="native"></generator> 
    </id> 
    <set name="addresses" table="AdressesMerchant" lazy="true"> 
    <key column="merchant_id"></key> 
    <many-to-many class="Adresses" column="address_id"/> 
    </set> 
</class> 

<class name="Address" table="Adresses" lazy="true"> 
    <id name="id" 
    type="long" 
    column="id"> 
    <generator class="native"></generator> 
    </id> 
    <set name="merchants" table="AdressesMerchant" lazy="true"> 
    <key column="adress_id"/> 
    <many-to-many column="merchant_id" class="Merchant"/> 
    </set> 
</class> 

Herhangi bir fikir?

+1

. Davranışı onaylar mısınız? Koleksiyonlarınız nasıl haritalanır? – Bozho

+0

@Bozho Sorguları kaydederek davranışı onaylayabilirim ve Hazırda bekletme adreslerinin adresleri yüklediğini görüyorum. Bu soruya eşlemeleri ekledim. – codea

+1

Bu konu değil, tersiyle işaretlenmiş çoktan çoğa ilişkilerden biri olmamalı mı? – Ralph

cevap

-1

Sen kriterleri FetchMode.EAGER sorgulamak ve kullanımı nesne kullanabilirsiniz.

+0

OP durumu yaptı, ** diğer ** ilişkili varlıkları yüklemek istemiyor. – luksch

1

Bunun için bulduk iki düzeltmeleri vardır. Kolay olan bir işlem yapmaktır. Eğer bussiness yönteminizde bir işlem başlatırsanız, bu yöntemin yaşam döngüsü içinde bunları istediğiniz zaman tembelleştirebilirsiniz. İşlemleriniz kapsayıcı olarak yönetiliyorsa, bu yönteme ulaşmak için @TransactionAttribute(TransactionAttributeType.REQUIRED) numaralı basit bir yöntem yeterli olacaktır. Başka bir yol Hibernate.initialize(object.getDesiredColletion()) kullanmaktır, bu aynı zamanda nesnelerinizi de getirecektir, ancak bir işlem de gereklidir. Bir işlem yoksa

Benim son çözümdür. Bu genel yöntem, temel olarak, sizin koleksiyonunuzu alır ve bunları ana nesnesine yerleştirmek için setter yöntemini kullanır. Bu süreci bir kimlikten geçerek ve genel olarak elde ederek geliştirebilirsiniz ve eğer java'daki güvenlik ayarlarını değiştirmeye özen göstermiyorsanız, koleksiyonları üst nesnenize (özel olsa bile) doğrudan ayarlayabilirsiniz. Bu kod oldukça azaltılabilir. Garip sesler

public Object fetchCollections(Object parent, Long id, Class<?>... childs) { 

    logger.debug("Need to fetch " + (childs.length) + " collections"); 
    String fieldName = ""; 
    String query = ""; 
    for (int i = 0; i < childs.length; i++) { 
     logger.debug("Fetching colletion " + (i + 1) + " of " 
       + (childs.length)); 
     logger.debug("Collection type is " + childs[i].getSimpleName()); 

     fieldName = findFieldName(childs[i], parent.getClass()); 
     if (fieldName == null) { 
      logger.debug("Trying to search with parent class"); 
      logger.debug(parent.getClass().getSuperclass()); 
      fieldName = findFieldName(childs[i], parent.getClass() 
        .getSuperclass()); 

     } 
     logger.debug("Creating query"); 
     query = "from " + childs[i].getSimpleName() + " obj " + "where " 
     + " obj." + fieldName + ".id=" + id; 
     logger.debug("Query= " + query); 
     Set collection = new HashSet(em.createQuery(query).getResultList()); 
     setCollection(parent, collection, fieldName, childs[i]); 

    } 

    return parent; 

} 


private String findFieldName(Class parentClass, Class childClass) { 
    String fieldName = null; 
    boolean isCollection = false; 
    logger.debug("Searching for field of type " 
      + childClass.getSimpleName()); 
    for (Field f : parentClass.getDeclaredFields()) { 

     String type = f.getGenericType().toString(); 
     if (f.getType().isInterface() 
       && f.getGenericType().toString().contains("java.util.Set")) { 
      logger.debug("This field is a collection"); 
      isCollection = true; 
      type = type.substring(type.indexOf("<") + 1); 
      type = type.substring(0, type.length() - 1); 
     } 

     if (isCollection) { 
      logger.debug("Field= " + f.getName() + " " 
        + f.getGenericType()); 
      if (type.equals(childClass.getName())) { 
       logger.debug("*****MATCH FOUND"); 
       fieldName = f.getName(); 
       break; 
      } 
     } else { 
      logger.debug("Type=" + f.getType().getName() + " childType=" 
        + childClass.getName()); 
      if (f.getType().getName().equals(childClass.getName())) { 
       logger.debug("*****MATCH FOUND"); 
       fieldName = f.getName(); 
       break; 
      } 

     } 

    } 

    return fieldName; 
} 


    private void setCollection(Object result, Set collection, String fieldName, 
     Class childClass) { 

    String methodName = "set" + fieldName.substring(0, 1).toUpperCase() 
    + fieldName.substring(1); 
    logger.debug("trivial setter is :" + methodName); 
    Class<?>[] args = new Class<?>[] { java.util.Set.class }; 
    // try the trivial case 
    boolean methodFound = false; 
    Method method = null; 
    try { 
     method = result.getClass().getMethod(methodName, args); 
     methodFound = true; 
    } catch (SecurityException e) { 
     e.printStackTrace(); 
    } catch (NoSuchMethodException e) { 
     logger.debug("Method not found by trivial method"); 

    } 

    if (!methodFound) { 
     FindMethod: for (Method m : result.getClass().getMethods()) { 
      // logger.debug(m.getName()); 
      for (Type t : m.getGenericParameterTypes()) { 
       // logger.debug("\t"+t); 
       String type = t.toString(); 
       type = type.substring(type.indexOf("<") + 1); 
       type = type.substring(0, type.length() - 1); 
       if (type.equals(childClass.getName())) { 
        logger.debug("***Found the Setter Method"); 
        method = m; 
        break FindMethod; 
       } 
      }// end for parameter Types 

     }// end for Methods 

    }// end if 

    invokeMethod(method, result, false, collection); 

} 



private void invokeMethod(Method method, Object obj, boolean initialize, 
     Object... args) { 

    try { 
     if (method != null) { 
      if (initialize) 
       Hibernate.initialize(method.invoke(obj, args)); 
      else 
       method.invoke(obj, args); 

     } 
     logger.debug("Method executed successfully"); 
    } catch (IllegalArgumentException e) { 

     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } 

} 
+2

Bunun benim problemimi çözeceğini sanmıyorum. Bir nesne listesi yüklediğimde, bu nesnenin çocuklarının yüklenmesini istemiyorum. Teşekkürler. – codea

İlgili konular