Announcement Announcement Module
Collapse
No announcement yet.
Direct Field Access Probelm Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Direct Field Access Probelm

    I have a web application using Spring-MVC 3.0.5. All of my controllers inherit from an abstract parent that initializes direct field access, which I prefer over bean property access.

    Code:
    @InitBinder
    public void initBinder( WebDataBinder binder ) {
       binder.initDirectFieldAccess();
    
      // register custom editors with binder
    }
    This works fine when my modelAttributes only contains simple types, but when they contain other objects I get errors rendering the page saying: Field 'object.property' does not exist.

    I thought using the following template in my jsp would work, but it doesn't

    Code:
    <form:form modelAttribute="modeled" >
         <form:input path="property"  />            //this works with both access methods
         <form:input path="object.property"  />   //this only works with property access
    </form:form>
    The above format works using bean property access, provided I add all the getters and setters, which I really don't want to do and why I avoided property access in the 1st place.

    Is there a way to use initDirectFieldAccess when the modeled object contains other objects? I'm thinking I may need a BeanWrapper, but I've never used it before. Any help would be appreciated.

    Thanks

  • #2
    Hello

    This works fine when my modelAttributes only contains simple types, but when they contain other objects I get errors rendering the page saying: Field 'object.property' does not exist.
    Post the complete error stack trace to have a better idea

    Normally I use to initialize an object within my controller in some special method and save it and using the SessionAttributes to be show in the jsp file with the form tag

    Comment


    • #3
      Custer is a Domain object used by Hibernate and an instance is part of the NewSale modeled on GET:

      Code:
      @RequestMapping( method=RequestMethod.GET)
      public void getNewSale( @RequestParam Long custId, final ModelMap model  ) {
         Customer cust = null;
      				
         if ( custId != - 1 ) {
            if ( custId == 0 ) 
               cust = new Customer();
            else 
      	 cust = customerService.findById( custId );
      			
            model.addAttribute( "newSale", new NewSale( cust )
         }		
      }
      Using Apache tiles for views.

      Cant post the full trace bc it's longer than 10K chars - here's the root cause:
      Code:
      org.springframework.beans.NotReadablePropertyException: Invalid property 'customer.id' of bean class [my.domain.support.web.dto.NewSale]: Field 'customer.id' does not exist
      	org.springframework.beans.DirectFieldAccessor.getPropertyValue(DirectFieldAccessor.java:104)
      	org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:98)
      	org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:224)
      	org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:120)
      	org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:174)
      	org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:194)
      	org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:160)
      	org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:147)
      	org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:138)
      	org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:122)
      	org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:408)
      	org.springframework.web.servlet.tags.form.HiddenInputTag.writeTagContent(HiddenInputTag.java:45)
      	org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
      	org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
      	org.apache.jsp.WEB_002dINF.jsp.sales_005fbody_jsp._jspx_meth_form_005fhidden_005f0(sales_005fbody_jsp.java:870)
      	org.apache.jsp.WEB_002dINF.jsp.sales_005fbody_jsp._jspService(sales_005fbody_jsp.java:272)
      	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
      	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
      	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
      	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
      	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      	org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968)
      	org.apache.jasper.runtime.PageContextImpl.doInclude(PageContextImpl.java:650)
      	org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:644)
      	org.apache.tiles.jsp.context.JspTilesRequestContext.include(JspTilesRequestContext.java:103)
      	org.apache.tiles.jsp.context.JspTilesRequestContext.dispatch(JspTilesRequestContext.java:96)
      	org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
      	org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
      	org.apache.tiles.renderer.impl.ChainedDelegateAttributeRenderer.write(ChainedDelegateAttributeRenderer.java:76)
      	org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
      	org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
      	org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:336)
      	org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:210)
      	org.apache.tiles.template.InsertAttributeModel.end(InsertAttributeModel.java:126)
      	org.apache.tiles.jsp.taglib.InsertAttributeTag.doTag(InsertAttributeTag.java:311)
      	org.apache.jsp.WEB_002dINF.jsp.layout_jsp._jspx_meth_tiles_005finsertAttribute_005f3(layout_jsp.java:158)
      	org.apache.jsp.WEB_002dINF.jsp.layout_jsp._jspService(layout_jsp.java:76)
      	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
      	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
      	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
      	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
      	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      	org.apache.tiles.servlet.context.ServletTilesRequestContext.forward(ServletTilesRequestContext.java:241)
      	org.apache.tiles.servlet.context.ServletTilesRequestContext.dispatch(ServletTilesRequestContext.java:222)
      	org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
      	org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
      	org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
      	org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:690)
      	org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:644)
      	org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:627)
      	org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321)
      	org.springframework.web.servlet.view.tiles2.TilesView.renderMergedOutputModel(TilesView.java:124)
      	org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
      	org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
      	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
      	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
      	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
      	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
      	javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
      	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      	org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
      	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368)
      	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
      	org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
      	org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      	org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169)
      	org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
      	org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
      	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
      	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

      Comment


      • #4
        Some observations

        1) I hope you are using in your controller @SessionAttributes("newSale")
        2) Post both POJO classes
        3) Are you sure is always executed the line model.addAttribute( "newSale", new NewSale( cust )?, you have a conditional block
        4) About

        Code:
        org.springframework.beans.NotReadablePropertyException: 
        Invalid property 'customer.id' of bean class 
        [my.domain.support.web.dto.NewSale]: 
        Field 'customer.id' does not exist
        	org.springframework.beans.DirectFieldAccessor.getPropertyValue(DirectFieldAccessor.java:104)
        Post your jsp code, a missing detail is there

        BTW your Tiles+Spring configuration work fine? I mean you can use Tiles for other view pages without problems?

        Comment


        • #5
          1) I hope you are using in your controller @SessionAttributes("newSale")
          I had forgotten this, but adding doesn't help as the page can't even load on the 1st GET

          2) Post both POJO classes
          Code:
          //Customer Entity
          @Entity
          @Table( name="Customer")
          public class Customer extends DbAssignedIdEntity implements DateEntered, Listable {
          
          	@Column( name="DATE_ENTERED" )
          	private Date dateEntered;
          	
          	@Column( name="FIRST_NAME" )
          	private String firstName;
          	
          	@Column( name="LAST_NAME" )
          	private String lastName;
          	
          	@Column( name="TITLE" )
          	private String title;
          	
          	@Column( name="COMPANY" )
          	private String company;
          	
          	@Column( name="EMAIL", unique=true )
          	private String email;
          	
          	@Column( name="PHONE_NUMBER", length=12 )
          	private String phone;
          	
          	@Column( name="REGISTERED" )
          	private boolean registered;
          	
          	@Column( name="HAS_SUPPORT" )
          	private boolean supportActive;
          	
          	@Column( name="ADDRESS_1")
          	private String address1;
          
          	@Column( name="ADDRESS_2")
          	private String address2;
          	
          	@Column( name="COUNTRY" )
          	private String country;
          	
          	@Column( name="CITY" )
          	private String city;
          	
          	@Column( name="STATE" )
          	private String state;
          	
          	@Column( name="ZIP_CODE" )
          	private String zipCode;
          	
          	@Column( name="INDUSTRY" )
          	private String industry;
          	
          	@Column( name="NUMBER_ASSETS" )
          	private Integer numberAssets;
          	
          	@Column( name="REGULATED" )
          	private boolean regulated = false;	
          	
          	@Override
          	public Date getDateEntered() {
          		return dateEntered;
          	}
          
          	@Override
          	public void setDateEntered(Date dateEntered) {
          		this.dateEntered = dateEntered;
          	}	
          		
          	@Override
          	public SelectValue getSelectValue() {
          		return new SelectValue( lastName + ", " + firstName + " (" + company + ")", id );
                  }
          }
          
          //New Sales modeled attributed that contains a customer
          public class NewSale {
          
          	@Min( value=1, message="You must select a Product")
          	private Long productId;
          	
          	private boolean newCust;
          	
          	private Customer customer;
          	
          	@Min( value=1, message="You must specify a Sales Rep")
          	private Long repId;
          	
          	public NewSale() {}
          	
          	public NewSale( Customer customer ) {
          		newCust = customer == null || customer.getId() == null;
          		this.customer = customer;
          	}	
          
                  //Add get / set methods for testing
          
          	public Long getProductId() {
          		return productId;
          	}
          	
          	public void setProductId( Long id ) {
          		productId = id;
          	}
          
          	public boolean isNewCust() {
          		return newCust;
          	}
          
          	public void setNewCust( boolean newCust ) {
          		this.newCust = newCust;
          	}
          
          	public Customer getCustomer() {
          		return customer;
          	}
          	
          	public void setCustomer( Customer customer) {
          		this.customer = customer;
          	}
          
          	public Long getRepId() {
          		return repId;
          	}
          
          	public void setRepId(Long repId) {
          		this.repId = repId;
          	}
          
          }
          3) Are you sure is always executed the line model.addAttribute( "newSale", new NewSale( cust )?, you have a conditional block
          My jsp checks for the existence of the objects, see below...

          Post your jsp code, a missing detail is there
          This is the the contents of the page body. The ${saleReps} & ${products} lists are loaded via @ModelAttribute methods in the controller.

          Note: I've also tried with Customer (capital 'C'), just to see, but that doesn't work either.

          Code:
          <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
          <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
          <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
          
          
          <c:if test="${not empty newSale}">
          	<form:form modelAttribute="newSale" >
          	
          		<c:if test="${not empty error}">
              		<p class="error" >${error}</p><br>
          	    </c:if>
          		
          		<form:hidden path="customer.id"/>		
          		<form:hidden path="newCust"/>
          		<form:hidden path="customer.registered" value="true" />
          		
          		<form:label path="customer.company" for="customer.company">Company Name</form:label>
          		<form:input path="customer.company"  /><form:errors path="customer.company" class="error" /><br>
          		
          		<form:label path="customer.industry" for="customer.industry">Industry</form:label>
          		<form:select path="customer.industry" >
          			<form:option label="-- Select an Industry -- " value="0" />
          			<form:options items="${industries}" itemLabel="selectLabel" itemValue="selectValue"/>				       	
          		</form:select><br>
          		
          		<form:label path="customer.firstName" for="customer.firstName">First Name</form:label>
          		<form:input path="customer.firstName" /><form:errors path="customer.firstName" class="error" /><br><br>
          		
          		<form:label path="customer.lastName" for="customer.lastName">Last Name</form:label>
          		<form:input path="customer.lastName" /><form:errors path="customer.lastName" class="error" /><br>
          		
          		<form:label path="customer.title" for="customer.title">Title</form:label>
          		<form:input path="customer.title" /><br>
          		
          		<form:label path="customer.email" for="customer.email">Email</form:label>
          		<form:input path="customer.email" /><form:errors path="customer.email" class="error" /><br>
          		
          		<form:label path="customer.phone" for="customer.phone">phone</form:label>
          		<form:input path="customer.phone" /><br>
          		
          		<form:label path="customer.address1" for="customer.address1">Address Line 1</form:label>
          		<form:input path="customer.address1" /><br>
          		
          		<form:label path="customer.address2" for="customer.address1">Address Line 2</form:label>
          		<form:input path="customer.address2" /><br>
          		
          		<form:label path="customer.city" for="customer.city">City</form:label>
          		<form:input path="customer.city" /> 
          		
          		<form:label path="customer.state" for="customer.state">State</form:label>
          		<form:input path="customer.state" />
          		
          		<form:label path="customer.zipCode" for="customer.zipCode" onkeypress="return numbersonly( this, event)" onpaste="return stopPaste( event )">Zip Code</form:label>
          		<form:input path="customer.zipCode" /><br>
          		
          		
          		<form:label path="repId" for="repId">Sales Rep</form:label>
          		<form:select path="repId" >
          			<form:option label="-- Select Sales Rep -- " value="0" />
          			<form:options items="${salesReps}" itemLabel="selectLabel" itemValue="selectValue"/>				       	
          		</form:select><form:errors path="repId" class="error" /><br>
          		
          		<form:label path="productId" for="productId">Product</form:label>
          		<form:select path="productId" >
          			<form:option label="--- Select Product ---" value="0" />
          			<form:options items="${products}" itemLabel="selectLabel" itemValue="selectValue"/>				       	
          		</form:select><form:errors path="productId" class="error" /><br>
          		<input type="submit" name="insert" value="Process"/>
          	</form:form>	
          </c:if>
          All my other pages render fine. Changing from direct field access to bean property access lets the page render, but the data isnt saved to the newSales.customer because of the lack of getters and setters. I did test adding get / set methods for a few customer properties and it work, but this is not the path I wish to take if it can be avoided.

          Thanks for all the help

          Comment


          • #6
            Hello

            Code:
            //Customer Entity
            @Entity
            @Table( name="Customer")
            public class Customer extends DbAssignedIdEntity
            I am assuming in your superclass the definition of the id property is defined like protected/private and with both public setter/getter, Am I correct?

            Note: I've also tried with Customer (capital 'C'), just to see, but that doesn't work either.
            If you are referring to @Table( name="Customer") it is related with Hibernate nothing related with the view layer

            Now these lines
            Code:
            <form:form modelAttribute="newSale" >
            ...
                  <form:hidden path="customer.id"/>	
            ...
            </form:form>
            assume or expect two things

            First
            that your NewSale class has a relation with the Customer class and has accessor methods, where it exists


            Code:
            public class NewSale {
            
            ...	
            	private Customer customer;
            	
            ...	
            
            	public Customer getCustomer() {
            		return customer;
            	}
            	
            	public void setCustomer( Customer customer) {
            		this.customer = customer;
            	}
            ...
            }
            until here we are fine

            Second:
            this Customer class has the id property with its public setter/getter. I guess it is within the DbAssignedIdEntity class, post your code

            Changing from direct field access to bean property access lets the page render, but the data isnt saved to the newSales.customer because of the lack of getters and setters. I did test adding get / set methods for a few customer properties and it work, but this is not the path I wish to take if it can be avoided.
            I am confused, what did you mean with the red part?, which setters/getters not exists?

            Comment


            • #7
              I do have an Id property in the superclass, but there is no set method. As the name implies, the id isn't assigned until hibernate persists the object. This means new instances are not safe to use in collections until after save and DbAssignedIdEntity implements equals and hashcode accordingly (I could use email as a natural key, but it's not needed right now).

              Something I don't think I was clear on: it's not the id field specifically, if I remove the hidden fields the error happens with customer.companyname. It's just the 1st property of customer it tries to access.

              I also wasn't very clear about how tested when I switched to bean property access. Simply changing the access method, without updating the POJOs just results in a different error:
              Invalid property 'customer.company' of bean class [com.primetechpa.support.web.dto.NewSale]: Bean property 'customer.company' is not readable or has an invalid getter method

              There is a getId() method, so it fails on the 1st one where there isn't a getter, makes sense. To get the page to render I had to add getters for all properties of Customer, but I didn't add the setters (in retrospect, should have just used STS to generate them for me), so when I POSTed the data was lost. All this tells me is that bean property access is working exactly how I'd expect it to. The problem is I'm expecting direct field access to work the same way, minus the get & set methods, but it isn't.

              I may dig around in the source code and see whats going on under the hood and maybe figure it out that way.

              Comment


              • #8
                I not positive since I'm not an expert in the framework code, but I may have found the issue:

                I started in the org.springframework.validation.DataBinder.initDire ctFieldAccess() method and eventually found that a org.springframework.beans.DirectFieldAccessor gets created using the following constructor:

                Code:
                /**
                	 * Create a new DirectFieldAccessor for the given target object.
                	 * @param target the target object to access
                	 */
                	public DirectFieldAccessor(Object target) {
                		Assert.notNull(target, "Target object must not be null");
                		this.target = target;
                		ReflectionUtils.doWithFields(this.target.getClass(), new ReflectionUtils.FieldCallback() {
                			public void doWith(Field field) {
                				fieldMap.put(field.getName(), field);
                			}
                		});
                		this.typeConverterDelegate = new TypeConverterDelegate(this, target);
                		registerDefaultEditors();
                		setExtractOldValueForEditor(true);
                	}
                Looking at ReflectionUtils.doWithFields()

                Code:
                /**
                	 * Invoke the given callback on all fields in the target class, going up the
                	 * class hierarchy to get all declared fields.
                	 * @param clazz the target class to analyze
                	 * @param fc the callback to invoke for each field
                	 * @param ff the filter that determines the fields to apply the callback to
                	 */
                	public static void doWithFields(Class<?> clazz, FieldCallback fc, FieldFilter ff)
                			throws IllegalArgumentException {
                
                		// Keep backing up the inheritance hierarchy.
                		Class<?> targetClass = clazz;
                		do {
                			Field[] fields = targetClass.getDeclaredFields();
                			for (Field field : fields) {
                				// Skip static and final fields.
                				if (ff != null && !ff.matches(field)) {
                					continue;
                				}
                				try {
                					fc.doWith(field);
                				}
                				catch (IllegalAccessException ex) {
                					throw new IllegalStateException(
                							"Shouldn't be illegal to access field '" + field.getName() + "': " + ex);
                				}
                			}
                			targetClass = targetClass.getSuperclass();
                		}
                		while (targetClass != null && targetClass != Object.class);
                	}
                it appears there is no recursive calls to get the properties of properties, which is what would be needed.

                So, if my analysis is correct and I wish to continue using direct field access I think I need to rework some of my objects.

                Right now I'm thinking to continue using direct field access and create a customerDTO that would have getters for all fields. Then create a static builder method on Customer.buildCustomer( CustomerDTO dto ). This way I avoid cluttering my Domain object with get / set methods. Suggestions on alternative paths forward for this would be appreciated.

                Thank again for the assistance

                Comment


                • #9
                  Hello

                  I think you are making complicated the things by yourself

                  Each variable or property of a class *must* be private/protected and its accessor methods setter/getters *should* exists and must be public
                  This is a law of gold

                  I do have an Id property in the superclass, but there is no set method.
                  You must have the setter method, because <form:hidden path="customer.id"/> expects get the id data to be shown in the jsp through the getter method and set the value when the form is submit using the setter method, even when it is hidden, it remains unchanged

                  it is a pattern or rule used practically for all the Java frameworks since Struts 1



                  As the name implies, the id isn't assigned until hibernate persists the object.
                  You are confused, you could be right about Hibernate about in which moment such assignation happen, but Spring MVC needs mandatory the setters to insert/update data and getters to get/load data, this data is closely related with the POJO used within your jsp file

                  In the MVC pattern, Spring MVC must has no none knowledge about the persistence framework used
                  Last edited by dr_pompeii; Jul 25th, 2011, 07:54 PM.

                  Comment

                  Working...
                  X