querydsl: Entity model using interfaces does not generate Q classes correctly

Our JPA entity model uses interfaces extensively and it seems that QueryDSL does not handle them correctly.

Here is an example of our model:

@Entity
@Table(name = "USERS")
@org.hibernate.annotations.AccessType("field")
@org.hibernate.annotations.Proxy(proxyClass = User.class)
public class UserImpl extends EntityImpl implements User {

    @NaturalId(mutable = true)
    @Column(name = "USERNAME", nullable = false)
    private String username;

    @ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER, targetEntity = PartyImpl.class)
    @JoinColumn(name = "PARTY_ID", nullable = false)
    private Party party;
}

@javax.persistence.Entity
@Table(name = "PARTY")
@org.hibernate.annotations.AccessType("field")
@org.hibernate.annotations.Proxy(proxyClass = Party.class)
public abstract class PartyImpl extends EntityImpl implements Party {

    @Column(name = "NAME", nullable = false)
    private String name;

}

Which generates a QUserImpl with the following field:

public final SimplePath<Party> party = createSimple("party", Party.class);

However, I believe it should look more like:

this.party = inits.isInitialized("party") ? new QPartyImpl(forProperty("party"), inits.get("party")) : null;

From reading the code it seems that the targetEntity attribute of the ManyToOne annotation is not being inspected. Is this type of model not supported? Or is there something else I need to do to make this work?

Regards, Damien

About this issue

  • Original URL
  • State: closed
  • Created 12 years ago
  • Comments: 29 (16 by maintainers)

Commits related to this issue

Most upvoted comments

The code is generating correctly now - thanks. But it creates a new problem that I hadn’t thought of.

Take the snippet below: public class QUserImpl extends EntityPathBase<UserImpl> { … public final com.walrus.model.domain.QPartyImpl party; … }

public class QPartyImpl extends EntityPathBase<PartyImpl> { … }

public User findUser(final Party party) {
    return getHibernateTemplate().execute(new HibernateCallback<User>() {
        @Nullable
        @Override
        public User doInHibernate(Session session) throws HibernateException, SQLException {
            com.mysema.query.jpa.hibernate.HibernateQuery query = new com.mysema.query.jpa.hibernate.HibernateQuery(session);
            return query.from(user).where(user.party.eq(party)).uniqueResult(user);
        }
    });

This no longer compiles because user.party is now a QPartyImpl (which is what I wanted) but the findUser method parameter is a Party (not a PartyImpl).

Unfortunately I can’t cast a Party to a PartyImpl, so there is no way to make the current code work. Is it possible to make the type parameter of EntityPathBase be Party instead? I think that would resolve this particular issue, although I’m not sure what other impact it might have.