Menu

HibernateBean Manager

ekobir
2008-09-29
2013-04-19
  • ekobir

    ekobir - 2008-09-29

    Hi Bruno

    I think there is a small problem in the new hibernate bean manager.... holdPersistentObject method in the Hibernate bean manager checks the property assaignability against  Collection and map (with isAssignableForm)

    and then if this case(isCollection variable) is false, it checks another instanceOf against collection and map
    in the body of if condition.

    if ((ClassUtils.immutable(propertyClass) == false) &&
                        (ClassUtils.isJavaPackage(propertyClass) == false) &&
                            (isCollection == false)) ------> I think this is a problem...
                    {

    Thanks
    Erkin

     
    • Bruno Marchesson

      Hi Erkin,

      Did you have a look at release 1.1.1 ?
      Here is the holdPersistentObject method :
      "protected boolean holdPersistentObject(Object pojo)
          {
              try
              {
              //    Precondition checking
              //
                  if (pojo == null)
                  {
                      return false;
                  }
                 
                  if (_persistenceUtil.isPersistentPojo(pojo) == true)
                  {
                      return true;
                  }
                 
              //    Iterate over properties
              //
                  BeanInfo info = Introspector.getBeanInfo(pojo.getClass());
                  PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
                  for (int index = 0; index < descriptors.length; index++)
                  {
                      PropertyDescriptor descriptor = descriptors[index];
                      Class<?> propertyClass = descriptor.getPropertyType();
                      if ((ClassUtils.immutable(propertyClass) == false) &&
                          (ClassUtils.isJavaPackage(propertyClass) == false))
                      {
                      //     Not a basic type, so a check is needed
                      //
                          // Get property value
                          Method readMethod = descriptor.getReadMethod();
                          readMethod.setAccessible(true);
                          Object propertyValue = readMethod.invoke(pojo, (Object[])null);
                         
                          if (propertyValue == null)
                          {
                              continue;
                          }
                          // Get real property class
                          propertyClass = propertyValue.getClass();
                         
                          if ((_classMapper != null) &&
                              (_classMapper.getSourceClass(propertyClass) != null))
                          {
                              propertyClass = _classMapper.getSourceClass(propertyClass);
                          }
                         
                          if (_persistenceUtil.isPersistentClass(propertyClass) == true)
                          {
                              return true;
                          }
                         
                          // collection and recursive search handling
                          if (propertyValue != null)
                          {
                              if (propertyValue instanceof Collection<?>)
                              {
                              //    Check collection values
                              //
                                  Collection<?> propertyCollection = (Collection<?>)propertyValue;
                                  for(Object value : propertyCollection)
                                  {
                                      if (holdPersistentObject(value) == true)
                                      {
                                          return true;
                                      }
                                  }
                              }
                              else if (propertyValue instanceof Map<?, ?>)
                              {
                              //    Check map entry and values
                              //
                                  Map<?,?> propertyMap = (Map<?, ?>) propertyValue;
                                  for(Map.Entry<?, ?> value : propertyMap.entrySet())
                                  {
                                      if ((holdPersistentObject(value.getKey()) == true) ||
                                          (holdPersistentObject(value.getValue()) == true))
                                      {
                                          return true;
                                      }
                                  }
                              }
                              else
                              {
                              //    Recursive search
                              //
                                  if (holdPersistentObject(propertyValue) == true)
                                  {
                                      return true;
                                  }
                              }
                          }
                         
                      }
                  }
                 
                  // No persistent property
                  return false;
              }
              catch (Exception e)
              {
                  throw new InvocationException(e);
              }
          }"

      Does it look ok to you ?

      Regards
      Bruno

       
    • ekobir

      ekobir - 2008-09-30

      Hey Bruno

      Thanks for your help again...  One more question,  Is latest version of the code always in trunk?

      Thanks
      Again

       
    • Bruno Marchesson

      Hi,

      The current release code is in branch '1.1'.
      The trunk contains the code of the upcoming release (1.2), which has been fully refactored (I rewrote the whole proxy informations handling, and added some new features).

      Regards
      Bruno

       
      • ekobir

        ekobir - 2008-09-30

        Hi Bruno

        It is really good info for me as I will not continue trying to build trunk....  Unfortunately (unfortunate because I don't want to disturb you.) I have one more question.

        When I try to send one of my domain object to client side, I'm getting security exception because of java assist proxy implementation. (host mode is working fine, but problem occurs on app server)

        But I got actually another error before that while hibernateBeanManager is cloning the object.

        PropertyDescriptor for javassist.util.proxy.MethodHandler in the generated class does not have any getter method for Method handler.  So

        "Method readMethod = descriptor.getReadMethod();" call in the holdPersistentObject method returns nulls and I'm getting null pointer exception.

        I put a simple hack as a work around but it didnt solve my security exception problem.

        Caused by: com.google.gwt.user.client.rpc.SerializationException: Type 'My_Domian_Object_$$_javassist_3' was not included in the set of types whic
        h can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.

        Thanks your help...

         
    • ekobir

      ekobir - 2008-09-30

      Hi Bruno

      Finally, I think I found a workaround for my problem. Let me explain you
      what happened.

      I'm trying build a system which is using gwt 1.5.2, hibernate
      3.2.6.ga, Spring 2.5.5,  hibernate4gwt1.1.1, gwt-sl 0.1.5a basically
      latest version of everything. (As project is not live yet, I would
      like to keep up with the release)

      The problem(it might be known but i wasnt aware) was getting an
      object ,which is enabled for lazy loading, from server side to client
      side.

      E.x

      class Service{
         Set<Contract> contracts;

      }

      class Contract{
           Service service;
        // Basic types and their getter setter

      }

      as you can see, there is a bidirectional relationship between Service
      and Contract. So hibernate-mapping settings in the Service.hbm.xml is
      like below

      <set name="contracts" inverse="true" lazy="true" cascade="all">
                  <key column="serviceId" not-null="true" />
                  <one-to-many class="myDomain.Contract"/>
      </set>

      The business scenario is getting all of contracts for a specific
      serviceId.
      Implementation at the server side was exactly what it is shown at
      http://www.hibernate.org/328.html

      so My generic DAO had following method.
      @SuppressWarnings("unchecked")
          public T findById(ID id, boolean lock) {
              T entity;
              if (lock)
                  entity = (T) getSession().load(getPersistentClass(), id,
      LockMode.UPGRADE);
              else
                  entity = (T) getSession().load(getPersistentClass(), id);

              return entity;
          }

      and My business method was

      Service getContracts(int serviceId){
          Service service = this.findById(serviceId, false);
          if (service != null) {
             Set<Contrat> contracts= service.getContracts();
             contracts.size(); //Note: this is a temporary solution to
      prevent JRE code optimization before going to production.
          }

          return service;

      }

      At this point getContracts method returned Service_javasisst as it is
      in the pre email..... And hibernate4gwt was not able to clone this
      object before serialization for RPC by throwing the exception in the
      previous email.

      In order to fix the problem, I changed load calls in the findById with
      get calls.

      @SuppressWarnings("unchecked")
          public T findById(ID id, boolean lock) {
              T entity;
              if (lock)
                  entity = (T) getSession().get(getPersistentClass(), id,
      LockMode.UPGRADE);
              else
                  entity = (T) getSession().get(getPersistentClass(), id);

              return entity;
          }

      So Only thing I need to be aware is not to expect HibernateException
      for unknown ids instead I need to do null checking on the returning
      obj.

      Thanks
      Erkin

       
    • ekobir

      ekobir - 2008-10-01

      Last Note:

      I just forgot to add the cause of this difference. If you look at the code in the

      org.hibernate.event.LoadEventListener.java, you will see the difference between GET LoadType and LOAD LoadType

      public static final LoadType GET = new LoadType("GET")
                  .setAllowNulls(true)
                  .setAllowProxyCreation(false) --> important
                  .setCheckDeleted(true)
                  .setNakedEntityReturned(false);
         
          public static final LoadType LOAD = new LoadType("LOAD")
                  .setAllowNulls(false)
                  .setAllowProxyCreation(true) --> important
                  .setCheckDeleted(true)
                  .setNakedEntityReturned(false);

      Thanks
      Erkin

       
    • Bruno Marchesson

      Hi Erkin,

      I really think that Hibernate "session.load" is pretty useless, except on very specific case, because it creates a uninitialized proxy that will lead to lazy loading on first access.
      Nevertheless, I consider the exception thrown on proxy as a bug and will try to fix it ASAP.

      Regards
      Bruno

       
      • ekobir

        ekobir - 2008-10-02

        Hi Bruno

        Thanks for your consideration...  I'm ready to help as well.

        Erkin

         

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.