简体   繁体   中英

many to one relationship in spring hibernate jpa

Can anyone show me how to resolve the following error in a spring mvc application that uses hibernate and jpa on top of a MySQL database?

[javax.el.PropertyNotFoundException: Property 'facilities' not found on type   
org.springframework.samples.knowledgemanager.model.ProviderCompany] with root cause
javax.el.PropertyNotFoundException: Property 'facilities' not found on type  
org.springframework.samples.knowledgemanager.model.ProviderCompany

The sql that creates the underlying tables is:

CREATE TABLE IF NOT EXISTS providerCompanies(
  id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(80),
  INDEX(name)
);

CREATE TABLE IF NOT EXISTS facilityAddresses(
  id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  company_id int(11) UNSIGNED NOT NULL,
  type_id int(11) UNSIGNED NOT NULL,
  facilityname varchar(50),
  address varchar(200),
  city varchar(200),
  state_id int(11) UNSIGNED NOT NULL,
  zip varchar(50),
  isHQ bool,
  FOREIGN KEY (company_id) REFERENCES providerCompanies(id), 
  FOREIGN KEY (type_id) REFERENCES locationTypes(id),
  FOREIGN KEY (state_id) REFERENCES states(id)

);

The ProviderCompany class is:

@Entity
@Table(name = "providerCompanies")
public class ProviderCompany extends NamedEntity {
    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(name="companyContactJunction",
            joinColumns={@JoinColumn(name="company_id")},
            inverseJoinColumns={@JoinColumn(name="contact_id")})
    protected Set<OfficeContact> companycontacts = new HashSet<OfficeContact>();

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "company",  fetch=FetchType.EAGER)
    protected Set<FacilityAddress> facilities = new HashSet<FacilityAddress>();

    ////////////OfficeContact methods
    protected void setContactsInternal(Set<OfficeContact> locs) {this.companycontacts = locs;}

    protected Set<OfficeContact> getContactsInternal() {
        if (this.companycontacts == null) {this.companycontacts = new HashSet<OfficeContact>();}
        return this.companycontacts;
    }

    public List<OfficeContact> getContacts() {
        List<OfficeContact> sortedLocs = new ArrayList<OfficeContact>(getContactsInternal());
        PropertyComparator.sort(sortedLocs, new MutableSortDefinition("contact", true, true));
        return Collections.unmodifiableList(sortedLocs);
    }

    public void addContact(OfficeContact oc) {
        getContactsInternal().add(oc);
        oc.addCompany(this);
    }

    public OfficeContact getContact(String fa) {return getContact(fa, false);}

    public OfficeContact getContact(String fa, boolean ignoreNew) {
        fa = fa.toLowerCase();
        for (OfficeContact e : getContactsInternal()) {
            if (!ignoreNew || !e.isNew()) {
                String compName = e.getLastName();
                compName = compName.toLowerCase();
                if (compName.equals(fa)) {return e;}
            }
        }
        return null;
    }
    ////////////Location methods
    protected void setFacilitiesInternal(Set<FacilityAddress> addresses) {this.facilities = addresses;}

    protected Set<FacilityAddress> getFacilitiesInternal() {
        if (this.facilities == null) {this.facilities = new HashSet<FacilityAddress>();}
        return this.facilities;
    }

    public List<FacilityAddress> getFacilities() {
        List<FacilityAddress> sortedLocations = new ArrayList<FacilityAddress>(getFacilitiesInternal());
        PropertyComparator.sort(sortedLocations, new MutableSortDefinition("location", true, true));
        return Collections.unmodifiableList(sortedLocations);
    }

    public void addFacility(FacilityAddress addr) {
        getFacilitiesInternal().add(addr);
        addr.setCompany(this);
    }

    public FacilityAddress getFacility(String address) {return getFacility(address, false);}

    public FacilityAddress getFacility(String addr, boolean ignoreNew) {
        addr = addr.toLowerCase();
        for (FacilityAddress address1 : getFacilitiesInternal()) {
            if (!ignoreNew || !address1.isNew()) {
                String compName = address1.getAddress();
                compName = compName.toLowerCase();
                if (compName.equals(addr)) {return address1;}
            }
        }
        return null;
    }
}

The FacilityAddress class is:

@Entity
@Table(name = "facilityAddresses")
public class FacilityAddress extends BaseEntity{
    @Column(name="address")
    protected String address;

    @Column(name="city")
    protected String city;

    @ManyToOne
    @JoinColumn(name = "state_id")
    protected State state;

    @Column(name="zip")
    protected String zip;

    @ManyToOne
    @JoinColumn(name = "company_id")
    protected ProviderCompany company;

    @ManyToOne
    @JoinColumn(name = "type_id")
    protected LocationType locationType;

    @Column(name = "facilityname")
    protected String facilityname;

    @Column(name = "isHQ")
    protected boolean isHQ;

    @ManyToMany(mappedBy="facilities")
    protected Set<Provider> providers = new HashSet<Provider>();

    public String getAddress(){return address;}
    public void setAddress(String addr){address=addr;}

    public String getCity(){return city;}
    public void setCity(String cty){city=cty;}

    public State getState(){return this.state;}
    public void setState(State st){state=st;}

    public String getZip(){return zip;}
    public void setZip(String zp){zip=zp;}

    protected void setCompany(ProviderCompany pc) {this.company = pc;}
    public ProviderCompany getCompany(){return this.company;}

    public LocationType getLocationType(){return locationType;}
    public void setLocationType(LocationType lt){locationType=lt;}

    public String getFacilityname(){return facilityname;}
    public void setFacilityname(String dir){facilityname=dir;}

    public boolean getIsHQ(){return isHQ;}
    public void setIsHQ(boolean ma){isHQ=ma;}

    public void addProvider(Provider p) {providers.add(p);}
    public Set<Provider> getProviders(){return this.providers;}

    public boolean isNew() {return (this.id == null);}
}

Here is BaseEntity.java :

@MappedSuperclass
public class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Integer id;

    public void setId(Integer id) {this.id = id;}

    public Integer getId() {return id;}

    public boolean isNew() {return (this.id == null);}

}

Here is NamedEntity.java :

@MappedSuperclass
public class NamedEntity extends BaseEntity {

    @Column(name = "name")
    private String name;

    public void setName(String name) {this.name = name;}

    public String getName() {return this.name;}

    @Override
    public String toString() {return this.getName();}

}

JpaProviderCompanyRepository is:

@Repository
public class JpaProviderCompanyRepositoryImpl implements ProviderCompanyRepository {

    @PersistenceContext
    private EntityManager em;

    @SuppressWarnings("unchecked")
    public Collection<ProviderCompany> findByName(String name) {
        System.out.println("---------------------- inside findByName() ");
        Query query = this.em.createQuery("SELECT DISTINCT company FROM ProviderCompany company left join fetch company.facilities WHERE company.name LIKE :name");
        System.out.println("---------------------- just created query. ");
        query.setParameter("name", name + "%");
        System.out.println("---------------------- just set parameter for query. ");
        Collection<ProviderCompany> results = query.getResultList();
        System.out.println("---------------------- just stored query results in collection. ");
        return results;//query.getResultList();
    }

    @Override
    public ProviderCompany findById(int id) {
        // using 'join fetch' because a single query should load both owners and pets
        // using 'left join fetch' because it might happen that an owner does not have pets yet
        System.out.println("<<<<<<<<<<<<<<<<<<<<<<<< inside Jpa Repository findById() >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        Query query = this.em.createQuery("SELECT company FROM ProviderCompany company left join fetch company.facilities WHERE company.id =:id");
        System.out.println("========================= Just set query. ");
        query.setParameter("id", id);
        System.out.println("------------------------- Just added parameter to query. ");
        ProviderCompany pc = (ProviderCompany) query.getSingleResult();
        System.out.println("------------------------- Just created ProviderCompany object from query result. ");
        return pc;
    }

    @Override
    public void save(ProviderCompany company) {
        if (company.getId() == null) {this.em.persist(company);}
        else {this.em.merge(company);}
    }
}

The complete stack trace is:

Jan 24, 2014 11:10:12 AM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
javax.el.PropertyNotFoundException: Property 'facilities' not found on type org.springframework.samples.knowledgemanager.model.ProviderCompany
    at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:237)
    at javax.el.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:214)
    at javax.el.BeanELResolver.property(BeanELResolver.java:325)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:85)
    at org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:104)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:183)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
    at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:1026)
    at org.apache.jsp.WEB_002dINF.jsp.companies.companiesList_jsp._jspService(companiesList_jsp.java:327)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:263)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.github.dandelion.datatables.core.web.filter.DatatablesFilter.doFilter(DatatablesFilter.java:73)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.github.dandelion.datatables.extras.servlet2.filter.DatatablesFilter.doFilter(DatatablesFilter.java:71)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Jan 24, 2014 11:10:12 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [KnowledgeManager] in context with path [/knowledgemanager] threw exception [javax.el.PropertyNotFoundException: Property 'facilities' not found on type org.springframework.samples.knowledgemanager.model.ProviderCompany] with root cause
javax.el.PropertyNotFoundException: Property 'facilities' not found on type org.springframework.samples.knowledgemanager.model.ProviderCompany
    at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:237)
    at javax.el.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:214)
    at javax.el.BeanELResolver.property(BeanELResolver.java:325)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:85)
    at org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:104)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:183)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
    at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:1026)
    at org.apache.jsp.WEB_002dINF.jsp.companies.companiesList_jsp._jspService(companiesList_jsp.java:327)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:263)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.github.dandelion.datatables.core.web.filter.DatatablesFilter.doFilter(DatatablesFilter.java:73)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.github.dandelion.datatables.extras.servlet2.filter.DatatablesFilter.doFilter(DatatablesFilter.java:71)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

I don't think this error has anything to do with JPA. Judging from the stacktrace, the problem here is that Spring MVC does not recognize the property in question. In order to be recognized as a property by Spring MVC, a variable has to have a javabeans-style getter and setter. After reexamning your code, I see that what you are missing the the setter of the facilities variable, Spring MVC requires this in order to be able to assign values to the variable.

It might be possible to customize this so that you won't have to add a setter you don't really want, but I don't know how. One of the thing I dislike the most about Spring MVC is the requirements it puts on the classes communicating with it, which are normally domain classes, classes you want to keep as clean as possible, where the requirements are controlled by domain logic, not a third party. Using a separate command-object for each page might mitigate this, but on the other hand it may become messy as well..

On a general notice, you have a lot of clutter in your imho, like @Column -annotations that just define the name of the column as what it would default to by JPA. These can just be removed (as well as @JoinColumn s where the name is _id, also a default.) Also, the overuse of special characters kinda hurts my eyes :p

I don't see any setter for the facilities property in ProviderCompany. Try adding a setFacilities() method.

It is because your ProviderCompany and its superclasses does not have a field locations . So you can not use this not existing field in a query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM