Results 1 to 10 of 10

Thread: Form backing object retrieved by Hibernate problem

  1. #1
    Join Date
    Aug 2004
    Location
    Kiev, Ukraine
    Posts
    7

    Default Form backing object retrieved by Hibernate problem

    My form backing object has a Map field.
    When I create new backing object by "new" operator, form is rendered correct:

    form.jsp
    --- cut ---
    <spring:bind path="myForm.myObject.mapField[${key}].stringField">
    <input type="text" name="<c:out value="${status.expression}"/>" value="<c:out value="${status.value}"/>"/>
    </spring:bind>
    --- end cut ---

    but, when I use this form for edit this object retrieved from DB by Hibernate, I has error:
    org.springframework.beans.NullValueInNestedPathExc eption: Invalid property 'myObject.mapField[12]' of bean class [tld.domain.myObject]: Value of nested property 'myObject.mapField[12]' is null
    org.springframework.beans.BeanWrapperImpl.getNeste dBeanWrapper(BeanWrapperImpl.java:482) org.springframework.beans.BeanWrapperImpl.getBeanW rapperForPropertyPath(BeanWrapperImpl.java:399) org.springframework.beans.BeanWrapperImpl.getBeanW rapperForPropertyPath(BeanWrapperImpl.java:400) org.springframework.beans.BeanWrapperImpl.getPrope rtyValue(BeanWrapperImpl.java:537) org.springframework.validation.BindException.getFi eldValue(BindException.java:265) org.springframework.web.servlet.support.BindStatus .(BindStatus.java:115) org.springframework.web.servlet.tags.BindStatus.(B indStatus.java:38) org.springframework.web.servlet.tags.BindTag.doSta rtTagInternal(BindTag.java:103) org.springframework.web.servlet.tags.RequestContex tAwareTag.doStartTag(RequestContextAwareTag.java:7 0)

    at the same time expression <c:out value="${myForm.myObject.mapField[key].stringField}"/> display value of stringField correctly

    I did debug application and find the following conclusion: this error throws becaouse map retrived by hibernate from DB has type net.sf.hibernate.collection.Map, but class org.springframework.beans.BeanWrapperImpl on method getPropertyValue has the folowing logic:
    --- cut ---
    ....
    import java.util.Map
    ....
    else if (value instanceof Map) {
    Map map = (Map) value;
    return map.get(key);
    }
    -- end cut ---

    i.e. problem exists because myObject.mapField has type net.sf.hibernate.collection.Map instead java.util.Map after retrieving by Hibernate,
    net.sf.hibernate.collection.Map ia a persistent wrapper for a java.util.Map.

    I think this problem exists for eny collection mapped to DB with Hibernate.

    Any suggestions about elegant solving of this problem ?

  2. #2
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    You could add a getter to your backing object that clone Hibernate Map and returns a true Java Map
    Code:
      public Map getJavaMapField&#40;&#41; &#123;
        return new HashMap &#40;mapField&#41;;
      &#125;
    I do not know if this is elegant enough, but you should not use this getter in your business layer to add / update / remove objects as it will disable Hibernate transparent persistance.
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  3. #3
    Join Date
    Aug 2004
    Location
    Kiev, Ukraine
    Posts
    7

    Default sorry, I have mistake about assumption of problem reason

    sorry, I have mistake about assumption of problem reason

    net.sf.hibernate.collection.Map implements java.util.Map and piece of code "value instanceof Map" can not be reason for exception as I assumed ...

    problem is on some other code, I do not know where
    but Spring bind tags can not extract collection elements retrieved from DB by Hibernate and genrate exception, at the same time it is work for java collections (java.util.HashMap for example) ...
    I can not explain this yet

    //

    thanx irbouho

  4. #4

    Default

    Just a guess: If you use lazy collections in Hibernate, then these collections can only be accessed as long as the hibernate session is open (typically this session is opened and closed again in the manager or DAO layer). So in this case you cannot access lazy collections in the view (jsp).

    This might explain why it works with the new non-hibernate object, but fails for hibernate managed collections.

    The solution would be the Open-Session-In-View-Pattern. I did not use it yet, but you will certainly find enough information about this, Spring supports it with an interceptor to open the hibernate session.

    My 2ct, hope this helps you!
    Sebastian

  5. #5
    Join Date
    Aug 2004
    Location
    Kiev, Ukraine
    Posts
    7

    Default some inattention

    thanx Sebastian

    but in my first post I did write about some interesting detail: JSTL expression
    Code:
    <c&#58;out value="$&#123;myForm.myObject.mapField&#91;key&#93;.stringField&#125;"/>
    located before <spring:bind> tag on the same form.jsp display this property correrctrly
    thereby lazy initialization innocent in the given situation IMHO

  6. #6
    Join Date
    Aug 2004
    Location
    Kiev, Ukraine
    Posts
    7

    Default

    it seems I found where is a problem
    my Map field has Integer keys
    Spring binding work correct only in case of String keys

  7. #7
    Join Date
    Sep 2004
    Posts
    18

    Default

    I would like to use Long or Integer as a key to a Map, but I was having the same problem with Spring not being able to bind this correctly (Only strings).

    Have you found a solution to this?

  8. #8
    Join Date
    Nov 2004
    Location
    Saint Louis, MO USA
    Posts
    9

    Default

    I have the same problem. But in my case the collection is a java.util.List.

    When I analyzed the collection. I found that the collection.size() returned me 2 instead of 1. When I iterated through the collection, I found there was null object added to the collection. I don't know where this null object comes from, but during the iteration process I removed the null object manually. This resulted in proper binding.

    Could the orginal author of this post verify the Map size against the expected Map size?

    I believe hibernate adds the extra null object. Since I just started playing with Spring/Hibernate all I can do right now is an educated guess.

    I request Experts to share their thoughts.

    Thanks,
    Arun
    Arun Viswanathan
    Dreamsoft Solutions, Inc.

  9. #9

    Default

    The issue reported by lis and rosco has a simple cause.

    The property path attribute used by the bind tag is just a regular String attribute.
    So when the JSP engine processes JSP code like this:
    Code:
    <spring&#58;bind path="myForm.myObject.mapField&#91;$&#123;key&#125;&#93;.stringField">
    The actual string value received by the BindTag is this:
    Code:
    myForm.myObject.mapField&#91;1&#93;.stringField
    The DataBinder/BeanWrapper divide this path in the various components:
    myForm, myObject, mapField, [1], stringField (or something similar).

    Now, at this point, the "[1]" component is just a regular String. While the expression evaluator of an JSP engine may have more information to infer types, the data binding framework only has a String to work with. Spring simply can't obtain the required type information from a Map instance.

    Of course, one workaround would be to amend the databinding code with something like:

    Code:
    // if the path element is a map ...
    if&#40;!map.isEmpty&#40;&#41;&#41;
    &#123;
        Class requiredClass = map.keySet&#40;&#41;.iterator&#40;&#41;.next&#40;&#41;.getClass&#40;&#41;;
        // Apply existing binding logic, e.g. call doTypeConversionIfNecessary&#40;&#41; etc
    &#125;
    This smells like a hack, but may be useful for users binding to Map instances with non-String keys.

    p.s. It would be a good idea to move this thread to the Web forum

  10. #10
    Join Date
    Aug 2004
    Location
    Southampton, UK
    Posts
    826

    Default

    Arun,

    You shoud really use Sets with Hibernate rather than Lists since you will end with a number of stray nulls if you use a List.

    Rob

Similar Threads

  1. Replies: 3
    Last Post: Jun 8th, 2010, 03:27 AM
  2. Replies: 2
    Last Post: Oct 10th, 2005, 05:12 PM
  3. Form model and hibernate object id
    By riankruger in forum Data
    Replies: 1
    Last Post: Sep 15th, 2005, 02:21 AM
  4. Loosing my SecureContext
    By sklakken in forum Security
    Replies: 3
    Last Post: Jul 21st, 2005, 01:44 PM
  5. Replies: 3
    Last Post: Nov 19th, 2004, 07:16 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •