I am building RESTful service with hibernate Jersey and Spring on java and realized that relationships between my entities should be without including instance of classes, just identifiers (foreign keys). But I have exceptions when try to query entities. I have following entities:
@Entity
@javax.persistence.Table(name = "manager_user")
public class ManagerUser extends User {
@ManyToOne(targetEntity = ShopAdminUser.class)
private Integer shopAdminUserId;
//...
}
@Entity
@javax.persistence.Table(name = "shop_admin_user")
public class ShopAdminUser extends User {
@Lob
private String contactData;
public String getContactData() {
return contactData;
}
public void setContactData(String contactData) {
this.contactData = contactData;
}
}
@Entity
@Inheritance(strategy= InheritanceType.TABLE_PER_CLASS)
public abstract class User {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Integer id;
private String firstName;
private String lastName;
@Temporal(TemporalType.DATE)
private Date dob;
@Enumerated(EnumType.STRING)
private Gender gender;
@Column(unique = true, nullable = false)
private String email;
@Column(nullable = false)
private String password;
@Lob
private String personalData;
@OneToOne(targetEntity = Photo.class)
private Integer photoId;
//...getters and setters
}
And I am getting exception in the next method:
@Transactional(readOnly = true)
public List<ManagerUser> getByShopAdminUserID(Integer id) {
Session session = sessionFactory.getCurrentSession();
List managerUsers = session.createQuery(
"from ManagerUser m where m.shopAdminUserId = :shopAdminUserId")
.setParameter("shopAdminUserId", id).list();
return managerUsers;
}
Stack trace:
Mar 28, 2015 4:10:56 PM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.foodservice.businesslogic.user.ShopAdminUser.id
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:60)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:346)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4746)
at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4465)
at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:243)
at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:293)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:537)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:174)
at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:67)
at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:616)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1901)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1862)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839)
at org.hibernate.loader.Loader.doQuery(Loader.java:910)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355)
at org.hibernate.loader.Loader.doList(Loader.java:2554)
at org.hibernate.loader.Loader.doList(Loader.java:2540)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370)
at org.hibernate.loader.Loader.list(Loader.java:2365)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1264)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
at com.foodservice.dao.ManagerUserDAO.getByShopAdminUserID(ManagerUserDAO.java:50)
at com.foodservice.dao.ManagerUserDAO$$FastClassBySpringCGLIB$$7447621a.invoke(<generated>)
...
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Integer field com.foodservice.businesslogic.user.User.id to java.lang.Integer
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:393)
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:57)
... 120 more
EDIT
My SQL provided by Hibernate
Hibernate:
select
manageruse0_.id as id1_0_,
manageruse0_.dob as dob2_0_,
manageruse0_.email as email3_0_,
manageruse0_.firstName as firstNam4_0_,
manageruse0_.gender as gender5_0_,
manageruse0_.lastName as lastName6_0_,
manageruse0_.password as password7_0_,
manageruse0_.personalData as personal8_0_,
manageruse0_.photoId_id as photoId11_0_,
manageruse0_.systemStatus as systemSt9_0_,
manageruse0_.userType as userTyp10_0_,
manageruse0_.shopAdminUserId_id as shopAdmi2_6_,
manageruse0_.state as state1_6_
from
manager_user manageruse0_
where
manageruse0_.shopAdminUserId_id=?
Hibernate:
select
shopadminu0_.id as id1_0_0_,
shopadminu0_.dob as dob2_0_0_,
shopadminu0_.email as email3_0_0_,
shopadminu0_.firstName as firstNam4_0_0_,
shopadminu0_.gender as gender5_0_0_,
shopadminu0_.lastName as lastName6_0_0_,
shopadminu0_.password as password7_0_0_,
shopadminu0_.personalData as personal8_0_0_,
shopadminu0_.photoId_id as photoId11_0_0_,
shopadminu0_.systemStatus as systemSt9_0_0_,
shopadminu0_.userType as userTyp10_0_0_,
shopadminu0_.contactData as contactD1_16_0_,
photo1_.id as id1_9_1_,
photo1_.image as image2_9_1_,
photo1_.name as name3_9_1_
from
shop_admin_user shopadminu0_
left outer join
photo photo1_
on shopadminu0_.photoId_id=photo1_.id
where
shopadminu0_.id=?
What I am doing wrong? Help me)
employee.getCompany().getCeo().getName(). Storing IDs completely defeats the purpose of associations. Make your domain model clean, and either annotate it to avoid serializing fields that shouldn't be serialized, or transform them to DTOs and serialize these DTOs, or use JSON views.