0

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)

9
  • realized that relationships between my entities should be without including instance of classes, just identifiers: well no, that's completely incorrect. The inverse is true. Commented Mar 28, 2015 at 14:42
  • In your case, if I want to get one entity then all children will also selected - it is takes the time. I want just to make in my entities identifiers on another entities, not whole. Commented Mar 28, 2015 at 14:46
  • That's what lazy associations are for. Read the documentation. Associations are between entities. Not between an entity and an Integer. Commented Mar 28, 2015 at 14:51
  • Thanks but I need just to have in my entities id of my children. I know about lazy loading and have faced the problem when Jersey was marshalling it into JSON. What I am doing wrong in context of this task? Commented Mar 28, 2015 at 14:55
  • What you're doing wrong is that you're assuming you can have associations with IDs of other entities. You can't. You can only have associations with other entities. The point of associations is to be able to get, for example, the name of the CEO of the company of an employee by doing 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. Commented Mar 28, 2015 at 15:01

2 Answers 2

1

i got a seem question.now i solve it.it's simple. your code-->

@ManyToOne(targetEntity = ShopAdminUser.class)
private Integer shopAdminUserId;

should be

@ManyToOne(targetEntity = ShopAdminUser.class)
@JoinColumn(name="shopAdminUserId" references...=""(i forget how to spell))
private ShopAdminUser shopAdminUser;

and so does this:

@OneToOne(targetEntity = Photo.class)
private Integer photoId;

should be

 @OneToOne(targetEntity = Photo.class)
@JoinColumn(name="photoId" references...=""(i forget how to spell))
private Photo photo;

because hibernate will auto converse the class to int or something else

Sign up to request clarification or add additional context in comments.

Comments

0

try to make no argument constructer in class (ShopAdminUser and ManagerUser). Hibernate uses it to instatiate entity.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.