Skip to content
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

No aliases found in result tuple [DATAJPA-885] #1242

Closed
spring-projects-issues opened this issue Apr 7, 2016 · 55 comments
Closed

No aliases found in result tuple [DATAJPA-885] #1242

spring-projects-issues opened this issue Apr 7, 2016 · 55 comments
Assignees
Labels
in: core type: bug

Comments

@spring-projects-issues
Copy link

spring-projects-issues commented Apr 7, 2016

ofbiz opened DATAJPA-885 and commented

After migrating Spring Data application from Gosling-SR4 to Hopper-SR1 release, all custom queries that extends JpaRepository throws the following message:

Caused by: java.lang.IllegalStateException: No aliases found in result tuple! Make sure your query defines aliases!
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter.convert(AbstractJpaQuery.java:246) [spring-data-jpa-1.10.1.RELEASE.jar:]
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:185) [spring-data-commons-1.12.1.RELEASE.jar:]
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter$1.convert(ResultProcessor.java:173) [spring-data-commons-1.12.1.RELEASE.jar:]
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:185) [spring-data-commons-1.12.1.RELEASE.jar:]
    at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:142) [spring-data-commons-1.12.1.RELEASE.jar:]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:107) [spring-data-jpa-1.10.1.RELEASE.jar:]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:92) [spring-data-jpa-1.10.1.RELEASE.jar:]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:482) [spring-data-commons-1.12.1.RELEASE.jar:]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460) [spring-data-commons-1.12.1.RELEASE.jar:]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    ... 113 more
public interface UserProfileAccessGroupRepository extends
        JpaRepository<UserProfileAccessGroup, UserProfileAccessGroupPK> {

    @Modifying
    @Query("DELETE FROM UserProfileAccessGroup upag WHERE upag.id.accessGroup = ?1")
    public void deleteByAccessGroup(AccessGroup accessGroup);

    @Modifying
    @Query("DELETE FROM UserProfileAccessGroup upag WHERE upag.id.userProfile = ?1")
    public void deleteByUserProfile(UserProfile userProfile);

    @Query("SELECT upag.id.accessGroup FROM UserProfileAccessGroup upag WHERE upag.id.userProfile = ?1")
    public List<AccessGroup> findAccessGroupByUserProfile(UserProfile userProfile);

    @Query("SELECT upag.id.accessGroup FROM UserProfileAccessGroup upag WHERE upag.id.userProfile = ?1 AND upag.id.accessGroup.functionality = false")
    public List<AccessGroup> findGroupByUserProfile(UserProfile userProfile);

    public List<UserProfileAccessGroup> findByExpirationDateBefore(Date date);
}
@Entity
public class UserProfileAccessGroup implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private UserProfileAccessGroupPK id;

    private Date expirationDate;

    @ManyToOne
    @JoinColumn(name = "authorizedBy")
    private UserProfile authorizedBy;

    public UserProfileAccessGroupPK getId() {

        if (id == null) {
            id = new UserProfileAccessGroupPK();
        }
        return id;
    }

    public void setId(UserProfileAccessGroupPK id) {
        this.id = id;
    }

    public Date getExpirationDate() {
        return expirationDate;
    }

    public void setExpirationDate(Date expirationDate) {
        this.expirationDate = expirationDate;
    }

    public UserProfile getAuthorizedBy() {
        return authorizedBy;
    }

    public void setAuthorizedBy(UserProfile authorizedBy) {
        this.authorizedBy = authorizedBy;
    }

    @Embeddable
    public static class UserProfileAccessGroupPK implements Serializable {

        private static final long serialVersionUID = 1L;

        @ManyToOne
        @JoinColumn(name = "accessGroupId")
        private AccessGroup accessGroup;

        @ManyToOne
        @JoinColumn(name = "userProfileId")
        private UserProfile userProfile;

        public UserProfileAccessGroupPK() {
        }

        public UserProfileAccessGroupPK(AccessGroup accessGroup, UserProfile userProfile) {
            this.accessGroup = accessGroup;
            this.userProfile = userProfile;
        }

        public AccessGroup getAccessGroup() {
            return accessGroup;
        }

        public void setAccessGroup(AccessGroup accessGroup) {
            this.accessGroup = accessGroup;
        }

        public UserProfile getUserProfile() {
            return userProfile;
        }

        public void setUserProfile(UserProfile userProfile) {
            this.userProfile = userProfile;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((accessGroup == null) ? 0 : accessGroup.hashCode());
            result = prime * result + ((userProfile == null) ? 0 : userProfile.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            UserProfileAccessGroupPK other = (UserProfileAccessGroupPK) obj;
            if (accessGroup == null) {
                if (other.accessGroup != null)
                    return false;
            } else if (!accessGroup.equals(other.accessGroup))
                return false;
            if (userProfile == null) {
                if (other.userProfile != null)
                    return false;
            } else if (!userProfile.equals(other.userProfile))
                return false;
            return true;
        }
    }
}

Affects: 1.10.1 (Hopper SR1)

Attachments:

Issue Links:

  • DATAJPA-913 Inconsistent behavior with projections when using @NamedQuery vs @Query
    ("is duplicated by")

  • DATAJPA-984 JPA projection query returning single non-standard JPA type results in "No aliases found in result tuple" error

  • DATACMNS-862 ReturnedInterface should not consider super interfaces of domain type projecting

  • DATAREST-841 Add support for query methods returning a projection

Backported to: 1.10.2 (Hopper SR2)

0 votes, 13 watchers

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 8, 2016

Oliver Drotbohm commented

Thanks for filing this. Any chance you add details about the AccessGroup type? Is it a class (an entity) or an interface? Looks like the newly introduced projection resolution mechanism is kicking in where it shouldn't. In case you have started debugging the project already, I'd be interested what type the source handed to ResultProcessor.process(…) is and why the first guard is not actually returning the object as is. You query definition seems to return objects that should be assignable to AccessGroup in the first place, right?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 8, 2016

ofbiz commented

Hi Oliver,

Yes, AccessGroup is an entity. Please see code and debug screenshot added at top post.

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.validation.constraints.NotNull;

import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.springframework.data.jpa.domain.AbstractPersistable;

/**
 * The persistent class for the AccessGroup database table.
 * 
 */
@Entity
public class AccessGroup extends AbstractPersistable<Integer> {

    private static final long serialVersionUID = 1L;

    @NotNull(message = "{field.name.empty}")
    private String name;

    private boolean readOnly;

    // bi-directional many-to-one association to AccessGroup
    @OneToOne
    @JoinColumn(name = "parentId")
    @NotFound(action = NotFoundAction.IGNORE)
    private AccessGroup parent;

    private Boolean functionality = true;

    @ManyToOne
    @JoinColumn(name = "portalUserIdOwner")
    private PortalUser owner;

    // bi-directional many-to-one association to AccessGroup
    @OneToMany(mappedBy = "parent")
    private List<AccessGroup> children;

    @OneToMany(mappedBy = "id.accessGroup")
    private List<UserProfileAccessGroup> userProfileAccessGroupList;

    private transient AccessibleItem module;
    private transient List<AccessibleItem> accessibleItems;
    private transient List<AccessGroup> functionalityList;
    private transient List<UserProfile> userProfileList;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isReadOnly() {
        return readOnly;
    }

    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    public AccessGroup getParent() {
        return this.parent;
    }

    public void setParent(AccessGroup parent) {
        this.parent = parent;
    }

    public Boolean getFunctionality() {
        return functionality;
    }

    public void setFunctionality(Boolean functionality) {
        this.functionality = functionality;
    }

    public PortalUser getOwner() {
        return owner;
    }

    public void setOwner(PortalUser owner) {
        this.owner = owner;
    }

    public List<AccessGroup> getChildren() {
        return children;
    }

    public void setChildren(List<AccessGroup> children) {
        this.children = children;
    }

    public List<UserProfileAccessGroup> getUserProfileAccessGroupList() {
        return userProfileAccessGroupList;
    }

    public void setUserProfileAccessGroupList(List<UserProfileAccessGroup> userProfileAccessGroupList) {
        this.userProfileAccessGroupList = userProfileAccessGroupList;
    }

    public AccessibleItem getModule() {
        return module;
    }

    public void setModule(AccessibleItem module) {
        this.module = module;
    }

    public List<AccessibleItem> getAccessibleItems() {
        return accessibleItems;
    }

    public void setAccessibleItems(List<AccessibleItem> accessibleItems) {
        this.accessibleItems = accessibleItems;
    }

    public List<AccessGroup> getFunctionalityList() {
        return functionalityList;
    }

    public void setFunctionalityList(List<AccessGroup> functionalityList) {
        this.functionalityList = functionalityList;
    }

    public List<UserProfile> getUserProfileList() {
        return userProfileList;
    }

    public void setUserProfileList(List<UserProfile> userProfileList) {
        this.userProfileList = userProfileList;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("[");

        if (getId() != null) {
            sb.append(getId());
        }
        sb.append("]");
        sb.append(name);

        return sb.toString();
    }
}

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 8, 2016

Oliver Drotbohm commented

I am still puzzled. Given you declare your query manually, the method that creates the Query instance is AbstractStringBasedJpaQuery.createJpaQuery(…). It uses the newly created infrastructure to inspect the return type for the case of a projection. For a ReturnedClass this forwards to isDto(). In this method, there's a check whether the return type is the same as the domain type, which it is. That means isDto() should return false which means AbstractStringBasedJpaQuery.createJpaQuery(…) should use the method not handing Tuple into the call to em.createQuery(…).

Can you verify this debugging the code? Are you sure that it's that particular method that's causing the issue?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 8, 2016

ofbiz commented

Oliver, I have updated the repository code at top of this post to show how is my current code. Sorry, I initially tried to simplify the post and keep it simple.
Let me know if you need further details.

See full stack exception:

Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: No aliases found in result tuple! Make sure your query defines aliases!; nested exception is java.lang.IllegalStateException: No aliases found in result tuple! Make sure your query defines aliases!
	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381) [spring-orm-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:227) [spring-orm-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:436) [spring-orm-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) [spring-data-jpa-1.10.1.RELEASE.jar:]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at com.sun.proxy.$Proxy81.findGroupByUserProfile(Unknown Source)
	at com.test.useraccess.service.impl.AccessGroupServiceImpl.findGroupByUserProfile(AccessGroupServiceImpl.java:234) [classes:]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_79]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_79]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_79]
	at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_79]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at com.sun.proxy.$Proxy85.findGroupByUserProfile(Unknown Source)
	at com.test.useraccess.form.UserProfileForm.executeAfterBind(UserProfileForm.java:90) [classes:]
	at com.test.fdn.vaadin.ui.window.AbstractWindowForm.buildLayoutPrivate(AbstractWindowForm.java:54) [foundation-starter-vaadin-1.0.6.jar:1.0.6]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_79]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_79]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_79]
	at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_79]
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:354) [spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:305) [spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133) [spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	... 89 more

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 9, 2016

Oliver Drotbohm commented

I think I understand the situation now. Thanks for reporting back. Working on a solution.

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 9, 2016

Steve Storey commented

I too found the same problem, and attach a reproducible test case (changing the POM version back to Gosling-SR4 causes the tests to pass, but the fail with Hopper-SR1). In my case it is caused by the fact that my Repository query returned a collection of a type other than the type of object declared for the repository (which appears to be the case in the Repository above as well).

I guess a workaround is simply to ensure you have a Repository per-type being returned in queries? In fact, perhaps that's a desirable requirement anyway?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 9, 2016

ofbiz commented

Excellent to hear it, I look forward to the fix!

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 9, 2016

Oliver Drotbohm commented

Steve Storey - Thanks for the attachement. You case is definitely related. However, in your case I'd argue the query returning Groups should stay in the GroupRepository, simply because it exists in the first place and thus turns Group into an aggregate root. Could be you just added it for the sake of the example but I thought I'd mention it.

There's a fix available in the current snapshots for master and the bugfix branch. The easiest way to try them is by using the BOM and changing the version to Hopper-BUILD-SNAPSHOT or Ingalls-BUILD-SNAPSHOT

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 9, 2016

ofbiz commented

Tks a lot Oliver! By any chance, would you know when Hopper-SR2 will be released?
I am really excited to move my projects to Hopper version

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 10, 2016

Shiro commented

I came upon the same error when querying for an enum property.

I have extended the example project to demonstrate the issue, which is still present in the latest Hopper-BUILD-SNAPSHOT

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 10, 2016

Oliver Drotbohm commented

Shiro — Great catch! I've pushed a fix for that to Spring Data Commons

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 10, 2016

Shiro commented

Thank you, this seems to fix it. (y)

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 10, 2016

Oliver Drotbohm commented

Thanks for verifying! Happy coding! 🙃

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 11, 2016

Jeffrey Haskovec commented

I am also seeing this issue. My query looks like this:

@Query("select distinct cciqie.companyCandidateId from CompanyCandidateIndexQueueItemError cciqie")
public Set<CompanyCandidate.Key> findAllCompanyCandidateIds();

The key type being returned is a custom type wrapper that we put over our primary keys for type safety. We declare them with the hibernate @TypeDef annotations in the package-info

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 11, 2016

Oliver Drotbohm commented

Jeffrey Haskovec - Are you saying you still that in the snapshots? Is Key a JPA known type (an embeddable or the like)?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 11, 2016

Jeffrey Haskovec commented

No I saw that in the Hopper SR1 release. I just wanted to report it in case we are a different scenario, since our type isn't an enum. The value inside of key is an Integer. We just wrap all of our primary keys in entity specific types to catch errors that people might make updating entity fields

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 11, 2016

Oliver Drotbohm commented

Okay, so not all hope is lost :). Feel free to give the snapshots a try. If the ID wrapper type is known to the JPA infrastructure (e.g. by being marked with @Embeddable), that should be fixed

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 12, 2016

Tristan Dupont commented

Hello, I still have the issue with the last snapshot:

Caused by: java.lang.IllegalStateException: No aliases found in result tuple! Make sure your query defines aliases!
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter.convert(AbstractJpaQuery.java:246) ~[spring-data-jpa-1.10.2.BUILD-20160411.180443-6.jar:?]
	at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:185) ~[spring-data-commons-1.12.2.BUILD-20160410.115832-5.jar:?]
	at org.springframework.data.repository.query.ResultProcessor$ChainingConverter$1.convert(ResultProcessor.java:173) ~[spring-data-commons-1.12.2.BUILD-20160410.115832-5.jar:?]
	at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:185) ~[spring-data-commons-1.12.2.BUILD-20160410.115832-5.jar:?]
	at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:142) ~[spring-data-commons-1.12.2.BUILD-20160410.115832-5.jar:?]
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:107) ~[spring-data-jpa-1.10.2.BUILD-20160411.180443-6.jar:?]
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:92) ~[spring-data-jpa-1.10.2.BUILD-20160411.180443-6.jar:?]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:482) ~[spring-data-commons-1.12.2.BUILD-20160410.115832-5.jar:?]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460) ~[spring-data-commons-1.12.2.BUILD-20160410.115832-5.jar:?]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:?]
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.12.2.BUILD-20160410.115832-5.jar:?]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:?]
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) ~[spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:?]
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	... 70 more

Here is the repository:

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;

import java.util.Collection;

public interface BattlePlayerRepository extends CrudRepository<BattlePlayer, Long> {

    @Query("select bp.battle from BattlePlayer bp where bp.playerId = :playerId")
    Collection<Battle> findBattleByPlayerId(@Param("playerId") final long playerId);

}

And here the two entities:

import org.springframework.data.jpa.domain.AbstractPersistable;

import javax.persistence.*;

@Entity
@Table(name = "Battle_Player")
public class BattlePlayer extends AbstractPersistable<Long> {

    static final String COLUMN_BATTLE_ID = "battle_id";
    static final String COLUMN_PLAYER_ID = "player_id";

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = COLUMN_BATTLE_ID, nullable = false)
    private Battle battle;

    @Column(name = COLUMN_PLAYER_ID, nullable = false)
    private long playerId;

    public Battle getBattle() {
        return battle;
    }

    public void setBattle(final Battle battle) {
        this.battle = battle;
    }

    public long getPlayerId() {
        return playerId;
    }

    public void setPlayerId(final long playerId) {
        this.playerId = playerId;
    }

}
import org.springframework.data.jpa.domain.AbstractPersistable;

import javax.persistence.*;

@Entity
@Table(name = "Battle")
public class Battle extends AbstractPersistable<Long> {

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

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(final String displayName) {
        this.displayName = displayName;
    }

}

Let me know if you need any other information

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 12, 2016

Oliver Drotbohm commented

That's weird. Would you mind looking at what this method returns? From what I can see Battle should be a JPA managed type and thus no tuples should be in place in the first place

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 12, 2016

Tristan Dupont commented

Ok, it works with the 1.11.0.BUILD-SNAPSHOT but not with the 1.10.2.BUILD-SNAPSHOT.

I thought it will be also available in the future 1.10.2.

So I can confirm the issue is fixed.

My bad :)

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 12, 2016

ofbiz commented

I thought the version 1.10.2.BUILD-SNAPSHOT would contain the fix.
I am missing the Hopper-SR2 to move on.
@Oliver, can you confirm it?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 12, 2016

Tristan Dupont commented

d64494ade65056325c9fb80c5383d1dea0bf822f is not yet merged on the branch 1.10.x.

spring-data-jpa(master)$ git branch --contains d64494ade65056325c9fb80c5383d1dea0bf822f
* master

master branch is 1.11.0.BUILD-SNAPSHOT

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 12, 2016

Oliver Drotbohm commented

Great catch, guys. I cherry-picked the relevant commits into 1.10.x. Snapshots available already

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Apr 13, 2016

Tristan Dupont commented

Thank you, the issue is fixed for me on both branches

@spring-projects-issues
Copy link
Author

spring-projects-issues commented May 23, 2016

Nickolay Bazhenov commented

Hello! I'm using Spring Data 1.11.0.BUILD-SNAPSHOT and still facing this issue:

org.springframework.dao.InvalidDataAccessApiUsageException: No aliases found in result tuple! Make sure your query defines aliases!; nested exception is java.lang.IllegalStateException: No aliases found in result tuple! Make sure your query defines aliases!
	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:437)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
	at com.sun.proxy.$Proxy39.findByUserIdIs(Unknown Source)
	at com.epam.dao.springdata.SpringDataTicketDao.getByUser(SpringDataTicketDao.java:22)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
	at com.epam.spring.LoggingAspect.logTimeMethod(LoggingAspect.java:34)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:620)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:609)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
	at com.sun.proxy.$Proxy42.getByUser(Unknown Source)
	at com.epam.service.impl.PlainTicketService.getBookedTickets(PlainTicketService.java:69)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
	at com.sun.proxy.$Proxy59.getBookedTickets(Unknown Source)
	at com.epam.facade.impl.SimpleBookingFacade.getBookedTickets(SimpleBookingFacade.java:96)
	at com.epam.integration.SimpleUseCase.testSimpleTestCase(SimpleUseCase.java:52)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.IllegalStateException: No aliases found in result tuple! Make sure your query defines aliases!
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter.convert(AbstractJpaQuery.java:246)
	at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:185)
	at org.springframework.data.repository.query.ResultProcessor$ChainingConverter$1.convert(ResultProcessor.java:173)
	at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:185)
	at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:142)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:107)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:92)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:482)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
	... 72 more

My repository:

public interface TicketRepository extends CrudRepository<PlainTicket, Long> {

    @Query("select t from PlainTicket t where t.eventId = ?1")
    List<Ticket> findByEventId(long eventId, Pageable pageable);

    @Query("select t from PlainTicket t where t.userId = ?1")
    List<Ticket> findByUserIdIs(long userId, Pageable pageable);

}

Entity:

// Some comments here
@Entity
@Table(name = "tickets")
public class PlainTicket implements Ticket, Serializable  {

	private static final long serialVersionUID = 1L;
	
	@Id
    @GeneratedValue(strategy = GenerationType.TABLE)
	@Column(name = "id")
    private long id;
    @Column(name = "event_id")
    private long eventId;
    @Column(name = "user_id")
    private long userId;
    @Column(name = "category")
    private Ticket.Category category;
    @Column(name = "place")
    private int place;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public long getEventId() {
        return eventId;
    }

    public void setEventId(long eventId) {
        this.eventId = eventId;
    }

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

    public Ticket.Category getCategory() {
        return category;
    }

    public void setCategory(Ticket.Category category) {
        this.category = category;
    }

    public int getPlace() {
        return place;
    }

    public void setPlace(int place) {
        this.place = place;
    }

    @Override
    public String toString() {
        return "PlainTicket{" +
                "id=" + id +
                ", eventId=" + eventId +
                ", userId=" + userId +
                ", category=" + category +
                ", place=" + place +
                '}';
    }
}

Could you please help me?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 1, 2016

Ben Madore commented

Ran across this as well.

@olivergierke This seems like a fairly major bug no? Does it affect custom queries on all Repository<T, ID> that return a Collection<T>? Short of switching to a snapshot (which, is really not a reasonable solution for a production app) is there any other workaround that you can suggest? If not, is this not enough of a major breaking bug (e.g. basic queries no longer work) that it would be worth pushing forward SR2?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 1, 2016

Oliver Drotbohm commented

Well, yes it is. The original bug didn't affect collection but queries with projections in the select clause. That is fixed (and already has been for a while) and will be released in the Hopper service release coming next week in preparation of Boot 1.4 RC1. I just filed and fixed DATACMNS-862 to cover the scenario above (interfaces returned that the domain type implements itself). Snapshot builds for that should be available in a couple of minutes.

It would indeed be helpful to at least temporarily upgrade to the latest snapshots (Hopper-BUILD-SNAPSHOT or Ingalls-BUILD-SNAPSHOT) to verify if the fixes that are already in place fix the issues you potentially see

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 7, 2016

Herman Meerlo commented

Any ETA on SR2? This bug is fairly blocking for me

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 7, 2016

Oliver Drotbohm commented

We're shooting for early next week. Do the snapshots work for you?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 7, 2016

Herman Meerlo commented

I have trouble using the SNAPSHOT build, I have no clue where to fetch it from and how to modify my pom for it. Can you give me a hint?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 7, 2016

Oliver Drotbohm commented

First, declare the snapshot repository (https://repo.spring.io/libs-snapshot). Then, if you're using Boot, just set the property spring-data-releasetrain.version to Hopper-BUILD-SNAPSHOT. If not, use the BOM in a <dependencyManagement /> section as shown here and set the version of the POM imported to Hopper-BUILD-SNAPSHOT

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 7, 2016

Herman Meerlo commented

It is not fixed for me in the Hopper-BUILD-SNAPSHOT release. But the pom for this release mentions 1.10.2.BUILD-SNAPSHOT for spring-data-jpa and the ticket you refer to has a fixed version of 1.12.2. So there seems to be a mismatch in versions

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 7, 2016

Oliver Drotbohm commented

JPA and Commons have different version numbers. As some of the fixes needed for this here were to be made in Commons that's just fine. Can you provide an example project that has a failing test case on the snapshots?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 7, 2016

Herman Meerlo commented

No sorry, that would cost me too much time right now which I don't have. All I can do to maybe guide you in the right direction is provide my repository class and the projection I return (removed some code to make it clearer):

@RepositoryRestResource(collectionResourceRel = "activiteiten", path = "activiteit")
public interface ActiviteitRepository extends PagingAndSortingRepository<Activiteit, Long>
{
	@Query("select a from Activiteit a where (a.machine = :machine or a.ladingmachine = :machine) and a.datum <= :end and a.datum >= :begin and a.type NOT IN (:exclude)")
	Page<ActiviteitFullProjection> findMachineAndDatumBetween(@Param("machine") Machine machine,
												@Param("begin") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date begin,
												@Param("end") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date end,
												@Param("exclude") List<ActiviteitType> notin,
												Pageable page);

}

And the projection:
@Projection(name = "full", types = { Activiteit.class})
public interface ActiviteitFullProjection
{
	public Long getId();

	public Date getDatum();

	public Date getBegintijd();

	public Date getEindtijd();

	public MetacomProject getProject();

	public MetacomPersoneel getMedewerker();

	public MetacomKostensoort getKsrt();

	public boolean isMeerwerk();

	public MetacomKostensoort getLading();

	public double getHoeveelheid();

	public int getKilometers();

	public ActiviteitType getType();

	public ActiviteitType getSoort();

	public Long getVerloning_minuten();

	public Long getDeclarabel_minuten();

	public BigDecimal getKosten_declarabel();

	public BigDecimal getEhp();

	public Point getBeginlocatie();

	public Point getEindlocatie();

	public Long getMinuten();

	public String getNotitie();

	public String getLocalid();

	public String getParentlocalid();

	public MetacomProject getFrom_project();

	public MetacomProject getTo_project();

	public Machine getMachine();

	public Machine getLadingmachine();

	public FuelMutationFullProjection getFuelmutation();

	public Long getFuelmutationid();

	public ActiviteitFullProjection getParent();

}

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 7, 2016

Oliver Drotbohm commented

I've pushed another fix to the handling of manually defined queries in combination with projection interfaces. Snapshots in place. Feel free to give them a spin

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 7, 2016

Herman Meerlo commented

Thanx for the quick responses, but unfortunately this build results in another error. If I replace the projection with the original entity it works fine:

2016-06-07 20:06:57.454 ERROR 23808 --- [nio-8090-exec-4] o.s.d.r.w.RepositoryRestExceptionHandler : PersistentEntity must not be null!

java.lang.IllegalArgumentException: PersistentEntity must not be null!
	at org.springframework.util.Assert.notNull(Assert.java:115) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.data.rest.webmvc.PersistentEntityResource$Builder.<init>(PersistentEntityResource.java:140) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at org.springframework.data.rest.webmvc.PersistentEntityResource$Builder.<init>(PersistentEntityResource.java:123) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at org.springframework.data.rest.webmvc.PersistentEntityResource.build(PersistentEntityResource.java:115) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.wrap(PersistentEntityResourceAssembler.java:74) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.toResource(PersistentEntityResourceAssembler.java:55) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.toResource(PersistentEntityResourceAssembler.java:38) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at org.springframework.data.web.PagedResourcesAssembler.createResource(PagedResourcesAssembler.java:200) ~[spring-data-commons-1.12.2.BUILD-20160410.115832-5.jar:na]
	at org.springframework.data.web.PagedResourcesAssembler.toResource(PagedResourcesAssembler.java:115) ~[spring-data-commons-1.12.2.BUILD-20160410.115832-5.jar:na]
	at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.entitiesToResources(AbstractRepositoryRestController.java:117) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.toResources(AbstractRepositoryRestController.java:78) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.toResource(AbstractRepositoryRestController.java:100) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at org.springframework.data.rest.webmvc.RepositorySearchController.executeSearch(RepositorySearchController.java:183) ~[spring-data-rest-webmvc-2.5.2.BUILD-20160427.134204-4.jar:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_31]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_31]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_31]
	at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_31]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832) ~[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743) ~[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961) ~[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895) ~[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) [spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) [spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) [spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:87) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at com.jb.api.SimpleCORSFilter.doFilter(SimpleCORSFilter.java:24) [classes/:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at com.jb.api.security.ErrorLogFilter.doFilter(ErrorLogFilter.java:28) [classes/:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at com.jb.api.model.SpringDataFixFilter.doFilter(SpringDataFixFilter.java:90) [classes/:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at com.jb.api.security.StatelessAuthenticationFilter.doFilter(StatelessAuthenticationFilter.java:25) [classes/:na]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at com.jb.api.SimpleCORSFilter.doFilter(SimpleCORSFilter.java:24) [classes/:na]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at com.jb.api.model.SpringDataFixFilter.doFilter(SpringDataFixFilter.java:90) [classes/:na]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) [spring-security-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_31]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_31]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.32.jar:8.0.32]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_31]

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jun 10, 2016

Oliver Drotbohm commented

That's a fundamental limitation of Spring Data REST in its current form as it can't necessarily always build proper responses from projections applied at the query method already. I've file DATAREST-841 to keep track of that and left some details about why this currently doesn't work

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Jul 30, 2016

Petar Tahchiev commented

I'm on Athens-RC1 which brings Hopper-SR2 and I am still experiencing the same exception. This is my method:

@Query(value = "from " + ContentPageEntityDefinition.NAME)
Collection<ContentPageEntityDefinition> findAllContentPages();

which is a valid hibernate HQL query. I've managed to overcome the problem by making it a JPQL query:

@Query(value = "select c from " + ContentPageEntityDefinition.NAME + " as c")
Collection<ContentPageEntityDefinition> findAllContentPages();

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 10, 2016

ruwen commented

Hi!

I was upgrading to 1.10.2 and the issue still persist. I have a composite primary key. My code looks more or less like this:

@Entity
@Table(name = "mytable")
public class MyClass {

    @EmbeddedId
    private MyPK myPK;

    public MyPK getMyPK() {
        return myPK;
    }

    public void setMyPK(MyPK myPK) {
        this.myPK = myPK;
    }
}

@Embeddable
public class MyPK implements Serializable {

    @Column(name = "mytype")
    @Convert(converter = MyTypeConverter.class)
    private MyType myType;

    @Column(name = "mystring")
    private String mystring = "";

    /** hashcode, equals, getters and setters */
}

My query:

@Query("select n.myPK.myType from MyClass n")
List<MyType> find();

produces the same error after upgrading.

If I change my code to

@Query("select n.myPK from MyClass n")
List<MyPK> find();

it works. But of course it returns the wrong type

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Paweł Jaguś commented

Got the same issue with composite keys after upgrading from Spring Boot 1.3.2 to 1.4.0. I guess it hasn't been completely corrected

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Oliver Drotbohm commented

Paweł Jaguś — Any chance you provide some details, a failing test case maybe?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Paweł Jaguś commented

In my case I use partial primary key in WHERE clause.

{{@Query("SELECT min(m.hourOfTheMatch) FROM Match m WHERE m.primaryKey.matchday = :matchday")
DateTime getFirstMatchStartDateTime(Matchday matchday);}}

I guess any test case with such a constellation will fail

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Oliver Drotbohm commented

I think it's related. DateTime can't be properly distinguished from a DTO type. I guess you're using dedicated AttributeConverter or Hibernate user type instances to map those to native database values?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Paweł Jaguś commented

So? It was working in the previous versions which means that in the following version it was broken.

I use org.jadira.usertype.dateandtime.joda.PersistentDateTime for this purpose, nothing special for Joda .

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime", parameters = {
            @Parameter(name = "databaseZone", value = "CET"),
            @Parameter(name = "javaZone", value = "CET") })
    private DateTime hourOfTheMatch = DateTime.now(Constants.TIME_ZONE);

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Oliver Drotbohm commented

With "related" I meant that it's not really the where clause that causing the issue but the type. And yes, you're right, that probably worked before as we started to inspect queries and return types more closely to allow the easy creation of projections using interfaces and DTOs in Hopper.

It's quite tricky in your case as for us there's hardly a way to detect that DateTime is a type internally handled by Hibernate. We can detect entities and embeddables, but unfortunately JPA doesn't expose means to find out about the types managed by internal conversion mechanisms. I guess moving to JDK 8 date types is not an option? They're easier to detect as we basically exclude everything from the java.… namespace anyway

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Paweł Jaguś commented

Moving to JDK 8 date and time types is not an option as JPA 2.1 does not support them (as stated here). I would have to write converters specially for that purpose

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Oliver Drotbohm commented

That's not entirely correct though. JPA 2.1 does not mandate support for a JPA 2.1 persistence provider. Recent Hibernate versions (everything starting at 5.0 AFAIR) just persist those types out of the box. Thorben even mentions that in the comments. I might ping him to maybe update the blog to maybe soften the tone slightly. "Why does JPA not support LocalDate and LocalDateTime?" is definitely implying something that's not really implied by the spec.

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Paweł Jaguś commented

Thanks for the hints. I will go with java.time.ZonedTimeDate then and let you know. In fact upgrading from Spring Boot 1.3.2 to 1.4.0 is for the future release of my app so I have some time to fiddle things up. It is a pity though that such "surprises" get into the release versions. :(

I will inform you whether this solves my problem

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 16, 2016

Oliver Drotbohm commented

That's usually caused by hardly anyone trying the milestones and release candidates — which in this case have been available since February 2016 ;)

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Aug 18, 2016

Paweł Jaguś commented

Switching to java.time.ZonedDateTime and upgrading to the newest version of Hibernate 5.2.2.Final solved the problem. This has in fact simplified the coding and removed some dependencies from pom.xml so I suppose there is always a silver lining

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Oct 20, 2016

Joris Kuipers commented

I'm still seeing this fail with Spring Data JPA 1.10.4. We have a method that returns a Joda LocalDate: the application has been started on Java 7 and uses Joda everywhere, even though it's already on Java 8 for quite some time now.
I do not consider it an option to migrate the entire app to the new date time library simply because of this change in Spring Data JPA, but I am seeing the same exception as reported above.

The query:

@Query("select r.reportDate from CommodityConnectionsComparisonReport r order by r.reportDate desc")
Set<LocalDate> findAllReportDates();

stacktrace:

org.springframework.dao.InvalidDataAccessApiUsageException: No aliases found in result tuple! Make sure your query defines aliases!; nested exception is java.lang.IllegalStateException: No aliases found in result tuple! Make sure your query defines aliases!

	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:227)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:436)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)

Apart from rewriting the query using JPA's API directly, is there a workaround that we can use? Maybe disable the entire projection feature, as it only gets in the way for our application?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Oct 20, 2016

Oliver Drotbohm commented

I guess the problem here is that there's no way for us to figure out that LocalDate is actually a JPA managed type, which makes the projection feature kick in in the first place.

I already thought about adding some smarts for the case that a single attribute is returned as it could also mean that this single attribute is supposed to be used as constructor argument for the DTO type returned. However, we could check whether that single value is assignable to the return type and then return it as is. I didn't add that code path yet as I thought it'd just complicate the resolution process even more. That said, I think your use case is a good example that we actually should do so.

Would you mind creating a new ticket copying the basic information?

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Oct 20, 2016

Joris Kuipers commented

Thanks, I'll do that! Will try to add a sample app with failing test as well

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Oct 20, 2016

Joris Kuipers commented

Created DATAJPA-984 with failing test sample

@spring-projects-issues
Copy link
Author

spring-projects-issues commented Oct 20, 2016

Oliver Drotbohm commented

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core type: bug
Projects
None yet
Development

No branches or pull requests

2 participants