New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange generics type parameter processing by the annotation processor #750

Closed
MartinAhrer opened this Issue May 8, 2014 · 19 comments

Comments

Projects
None yet
4 participants
@MartinAhrer

We have a rather complex inheritance tree based on spring-data-jpa's AbstractPersistable. We have run into an issue with the annotation process not processing generics parameters properly: AbstractPersistable is using PK as type parameter while one of our subclasses BasePersistable is using T for passing on the same type parameter. As a result the annotation processor returns with:

Caused by: java.lang.IllegalStateException: Did not find type PK in [java.io.Serializable]
        at com.mysema.query.codegen.TypeResolver.resolveVar(TypeResolver.java:80)
        at com.mysema.query.codegen.TypeResolver.resolve(TypeResolver.java:44)
        at com.mysema.query.codegen.Property.createCopy(Property.java:88)
        at com.mysema.query.codegen.EntityType.include(EntityType.java:226)
        at com.mysema.query.apt.AbstractQuerydslProcessor.addSupertypeFields(AbstractQuerydslProcessor.java:415)
        at com.mysema.query.apt.AbstractQuerydslProcessor.processAnnotations(AbstractQuerydslProcessor.java:166)
        at com.mysema.query.apt.AbstractQuerydslProcessor.process(AbstractQuerydslProcessor.java:99)

This is the code base:

@Entity
@Getter
@Setter(AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Where(clause = "deleted = 'false'")
@SQLDelete(sql = "UPDATE UserAccount SET deleted ='true' WHERE id = ?")
public class UserAccount extends BaseReferencablePersistable<Long> {
    ...
@MappedSuperclass
public abstract class BaseReferencablePersistable<PK extends Serializable> extends BasePersistable<PK> implements Referenceable {
    ...
@MappedSuperclass
@EntityListeners({UpdateInfoListener.class})
@TypeDef(defaultForType = DateTime.class, typeClass = PersistentDateTime.class)
public abstract class BasePersistable<PK extends Serializable> extends AbstractPersistable<PK> implements UpdateInfo {
    ...
@MappedSuperclass
public abstract class AbstractPersistable<PK extends Serializable> implements Persistable<PK> {
    ...

Once BasePersistable is also using PK as type parameter name the annotation processor successfully processes the classes.

@MartinAhrer MartinAhrer changed the title from Generics type parameter processing by the annotation processor to Strange generics type parameter processing by the annotation processor May 8, 2014

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest May 8, 2014

Member

Could you also provide the annotations for the other classes?

Member

timowest commented May 8, 2014

Could you also provide the annotations for the other classes?

@MartinAhrer

This comment has been minimized.

Show comment
Hide comment
@MartinAhrer

MartinAhrer May 9, 2014

I have updated the code paragraphs to include all of the class annotations. You see that we also use Lombok. But Lombok we have sorted out to cause the problem.

I have updated the code paragraphs to include all of the class annotations. You see that we also use Lombok. But Lombok we have sorted out to cause the problem.

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest May 9, 2014

Member

Could you also state which Querydsl version you use?

Member

timowest commented May 9, 2014

Could you also state which Querydsl version you use?

@MartinAhrer

This comment has been minimized.

Show comment
Hide comment
@MartinAhrer

MartinAhrer May 9, 2014

It's the latest is the greatest 3.3.3.

It's the latest is the greatest 3.3.3.

@timowest timowest added the bug label May 9, 2014

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest May 15, 2014

Member

Sorry, I've not been able to reproduce this in the tests. Could you provide a minimal project which reproduces the issue?

Member

timowest commented May 15, 2014

Sorry, I've not been able to reproduce this in the tests. Could you provide a minimal project which reproduces the issue?

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Jun 14, 2014

Member

@MartinAhrer Which JDK version did you use? I will take now some time to go over the open Querydsl bug reports.

Member

timowest commented Jun 14, 2014

@MartinAhrer Which JDK version did you use? I will take now some time to go over the open Querydsl bug reports.

@MartinAhrer

This comment has been minimized.

Show comment
Hide comment
@MartinAhrer

MartinAhrer Jun 14, 2014

It's JDK 1.7.0_55 and now also testing with JDK 1.8.0_05 with the same behaviour

It's JDK 1.7.0_55 and now also testing with JDK 1.8.0_05 with the same behaviour

@MartinAhrer MartinAhrer reopened this Jun 14, 2014

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Jun 14, 2014

Member

An example project (with a failing build) for this case would be great. Unfortunately I have still not yet been able to reproduce the issue.

Member

timowest commented Jun 14, 2014

An example project (with a failing build) for this case would be great. Unfortunately I have still not yet been able to reproduce the issue.

@MartinAhrer

This comment has been minimized.

Show comment
Hide comment
@MartinAhrer

MartinAhrer Jun 14, 2014

I'm working on that right now - sorry for that delay!

I'm working on that right now - sorry for that delay!

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Jul 19, 2014

Member

@MartinAhrer Have you been able to create an isolated example project?

Member

timowest commented Jul 19, 2014

@MartinAhrer Have you been able to create an isolated example project?

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Sep 27, 2014

Member

@MartinAhrer Do you still have the same issue? A sample project would be great to be able to squash this bug.

Member

timowest commented Sep 27, 2014

@MartinAhrer Do you still have the same issue? A sample project would be great to be able to squash this bug.

@MartinAhrer

This comment has been minimized.

Show comment
Hide comment
@MartinAhrer

MartinAhrer Oct 1, 2014

Sorry, I have done multiple iterations by stripping off code and dependencies all not showing the effect. Still the issue exists in my original project. But as I have a working workaround by using matching generics type parameter names I would totally accept if you closed this issue as it has been around for a while now.

Sorry, I have done multiple iterations by stripping off code and dependencies all not showing the effect. Still the issue exists in my original project. But as I have a working workaround by using matching generics type parameter names I would totally accept if you closed this issue as it has been around for a while now.

@senita

This comment has been minimized.

Show comment
Hide comment
@senita

senita Oct 29, 2014

I have the same error. I am using spring-data and have classes that inherits from AbstractPersistable (spring-data-jpa). It is a rather "complex" structure.

From top down it is like this:
spring-data-jpa class

@MappedSuperclass
public abstract class AbstractPersistable<PK extends Serializable> implements Persistable<PK> {
...

Generic base class for all my entities:

@MappedSuperclass
@Access(AccessType.PROPERTY)
public class GenericEntity<ID extends Serializable> extends AbstractPersistable<ID> {
...

Example of implementing class:

@Entity
@Access(AccessType.PROPERTY)
@AttributeOverride(name = "id", column = @Column (name="compositeComponentId"))
public class CompositeComponent extends GenericEntity<Integer> {
    ...

    @Transient
    public Integer getCompositeComponentId() {
        return getId();
    }
    public void setCompositeComponentId(Integer compositeComponentId) {
        setId(compositeComponentId);
    }

I pinpointed when it stopped working. In TypeResolver you went from:

    if (index > -1) {
            // get binding of var via model supertype
            Supertype type = context.getSuperType();            
            while (!type.getEntityType().equals(declaringType)) {
                type = type.getEntityType().getSuperType();                
            }
            return Lists.newArrayList(
                    type.getType().getParameters().get(index), 
                    type.getType());
        } else {
            // TODO : error
            return Collections.emptyList();
        }

to

    if (index == -1) {
            throw new IllegalStateException("Did not find type " + varName
                    + " in " + declaringType.getParameters());
        }

in version 2.8.2 to 3.x. I am right now trying to get 3.0.0 to work. I've also tried 3.3.4. Hope this helps!

senita commented Oct 29, 2014

I have the same error. I am using spring-data and have classes that inherits from AbstractPersistable (spring-data-jpa). It is a rather "complex" structure.

From top down it is like this:
spring-data-jpa class

@MappedSuperclass
public abstract class AbstractPersistable<PK extends Serializable> implements Persistable<PK> {
...

Generic base class for all my entities:

@MappedSuperclass
@Access(AccessType.PROPERTY)
public class GenericEntity<ID extends Serializable> extends AbstractPersistable<ID> {
...

Example of implementing class:

@Entity
@Access(AccessType.PROPERTY)
@AttributeOverride(name = "id", column = @Column (name="compositeComponentId"))
public class CompositeComponent extends GenericEntity<Integer> {
    ...

    @Transient
    public Integer getCompositeComponentId() {
        return getId();
    }
    public void setCompositeComponentId(Integer compositeComponentId) {
        setId(compositeComponentId);
    }

I pinpointed when it stopped working. In TypeResolver you went from:

    if (index > -1) {
            // get binding of var via model supertype
            Supertype type = context.getSuperType();            
            while (!type.getEntityType().equals(declaringType)) {
                type = type.getEntityType().getSuperType();                
            }
            return Lists.newArrayList(
                    type.getType().getParameters().get(index), 
                    type.getType());
        } else {
            // TODO : error
            return Collections.emptyList();
        }

to

    if (index == -1) {
            throw new IllegalStateException("Did not find type " + varName
                    + " in " + declaringType.getParameters());
        }

in version 2.8.2 to 3.x. I am right now trying to get 3.0.0 to work. I've also tried 3.3.4. Hope this helps!

@Shredder121

This comment has been minimized.

Show comment
Hide comment
@Shredder121

Shredder121 Oct 29, 2014

Member

The IllegalStateException is just the implementation of the //TODO: error

@timowest I now see the problem, and I will push the updated test case.

Member

Shredder121 commented Oct 29, 2014

The IllegalStateException is just the implementation of the //TODO: error

@timowest I now see the problem, and I will push the updated test case.

@Shredder121

This comment has been minimized.

Show comment
Hide comment
@Shredder121

Shredder121 Oct 29, 2014

Member
param instanceof TypeExtends && Objects.equal(((TypeExtends)param).getVarName(), varName)

When the names are different, so PK and T, the parameters are not considered to be the same ones.

Member

Shredder121 commented Oct 29, 2014

param instanceof TypeExtends && Objects.equal(((TypeExtends)param).getVarName(), varName)

When the names are different, so PK and T, the parameters are not considered to be the same ones.

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Oct 29, 2014

Member

Yes, looks like there is an issue in the varName usage.

Member

timowest commented Oct 29, 2014

Yes, looks like there is an issue in the varName usage.

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Nov 3, 2014

Member

@Shredder121 I could try a fix now. Which of the two branches should I use as a basis?

Member

timowest commented Nov 3, 2014

@Shredder121 I could try a fix now. Which of the two branches should I use as a basis?

@Shredder121

This comment has been minimized.

Show comment
Hide comment
@Shredder121

Shredder121 Nov 3, 2014

Member

The first branch (i750) is the case for this issue, so that one should be fixed first.

The second one (i750-2) is a case that the current logic doesn't support (so that one could be fixed, but maybe at a later time and since it is also a case of strange type parameter handling, I categorized it under this issue)

Member

Shredder121 commented Nov 3, 2014

The first branch (i750) is the case for this issue, so that one should be fixed first.

The second one (i750-2) is a case that the current logic doesn't support (so that one could be fixed, but maybe at a later time and since it is also a case of strange type parameter handling, I categorized it under this issue)

@timowest timowest added this to the 3.6.0 milestone Nov 5, 2014

@Shredder121 Shredder121 closed this in #1030 Nov 17, 2014

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Nov 30, 2014

Member

Released in 3.6.0

Member

timowest commented Nov 30, 2014

Released in 3.6.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment