In this post, we discuss yet another reason for having a mapping error from Hibernate. This specific one is called a PropertyNotFoundException. If you have made sure that your property is correctly mapped to the database table, with correct column names and a getter and a setter for the property, then read on!.
Let us get started by checking our faulty code….
@Entity @Table(name = "customer_address") public class CustomerAddress { private long id; private String zipCode; ....................... ....................... @Column(name = "zip_code" ,nullable = false) public String getZipCode() { return zipCode; } public void setZipCode() { this.zipCode = "43221"; } }
If we attempt to start up our application, we will get the following error message:
org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:123) at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:77) at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:154) at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:295) at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939) at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ... 44 more Caused by: org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer] at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:91) at org.hibernate.tuple.entity.EntityTuplizerFactory.constructDefaultTuplizer(EntityTuplizerFactory.java:116) at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:382) at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:551) at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:124) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:96) ... 52 more Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:88) ... 61 more Caused by: org.hibernate.PropertyNotFoundException: Could not locate setter method for property [com.nullbeans.persistence.models.CustomerAddress#zipCode] at org.hibernate.internal.util.ReflectHelper.findSetterMethod(ReflectHelper.java:607) at org.hibernate.property.access.internal.PropertyAccessBasicImpl.<init>(PropertyAccessBasicImpl.java:44) at org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl.buildPropertyAccess(PropertyAccessStrategyBasicImpl.java:27) at org.hibernate.mapping.Property.getGetter(Property.java:308) at org.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertyGetter(PojoEntityTuplizer.java:254) at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:144) at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:58) ... 66 more Process finished with exit code -1
Notice the most inner cause is a PropertyNotFoundException.
Did you notice the bug?
Taking a look at the code, we can see that the property does exist. A getter and a setter do exist for the zipCode property as well. So what was the issue?
The issue is that Hibernate expects that you follow a standard JavaBean pattern, implementing getters and setters for each property. Hibernate also expects that your setter takes as an argument the value of the property to be set. Since our setter had no arguments, Hibernate could not find a setter to work with. To correct this issue, we simply add another setter to our class which takes the zipCode as an argument. If you do not want to expose that setter, you can simply set the setter access to “private”. Hibernate uses reflection to find the getters and setters, so the protection level should not matter.
//Setter for Hibernate private void setZipCode(String zipCode) { this.zipCode = zipCode; } //Setter to be used by API users public void setZipCode() { this.zipCode = "43221"; }
If you have liked this content, then please follow us on twitter by clicking on the follow button below in order to get our latest updates 🙂