2 votes

Hibernate spatial jpa query ne fonctionne pas

J'ai écrit une requête spatiale pour trouver le point le plus proche d'un emplacement. Mais Hibernate obtient une exception. Mon application avec Spring boot 1.5.7

@Repository
@Transactional(readOnly = true)
public interface PlaceRepository extends JpaRepository<PlaceEntity, Long> {
    PlaceEntity findByCode(String code);
    PlaceEntity findByName(String name);
    @Query("select l from PlaceEntity l where within(l.location, :filter) = true")
    List<PlaceEntity> findLocationWithin(Geometry filter);
}

Voici les paramètres de ma classe d'entité

@Data
@Entity(name = "Place")
public class PlaceEntity extends BaseEntity {

@Type(type = "org.hibernate.spatial.GeometryType")
@Column(name = "LOCATION",columnDefinition = "POINT")
    private Point location;
}

Les autres paramètres sont

@Id
@GeneratedValue
@Column(name = "ID")
private long id;
@Column(name = "NAME")
private String name;
@Column(name = "CODE")
private String code;
@Column(name = "LONGITUDE")
private Double longitude;
@Column(name = "LATITUDE")
private Double latitude;

Voici mon build.gradle.

compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.hibernate:hibernate-core:4.3.0.Final')
compile("org.hibernate:hibernate-spatial:4.3")
compile("org.hibernate:hibernate-entitymanager:4.3.0.Final")
compile('mysql:mysql-connector-java')
compile('org.projectlombok:lombok:1.14.8')
compile('org.springframework.boot:spring-boot-starter-web')
compile('com.vividsolutions:jts:1.13')
testCompile('org.springframework.boot:spring-boot-starter-test')

Configuration

@EnableWebMvc
@Configuration
public class AppConfig {

}

Mais lorsque je déploie le serveur, je reçois une exception.

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'pathController': Unsatisfied dependency expressed through field 'pathService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'pathServiceImpl': Unsatisfied dependency expressed through field 'placeRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'placeRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.fm.assignment.core.dao.PlaceRepository.findLocationWithin(com.vividsolutions.jts.geom.Geometry)!
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'pathServiceImpl': Unsatisfied dependency expressed through field 'placeRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'placeRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.fm.assignment.core.dao.PlaceRepository.findLocationWithin(com.vividsolutions.jts.geom.Geometry)!
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:58

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'placeRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.fm.assignment.core.dao.PlaceRepository.findLocationWithin(com.vividsolutions.jts.geom.Geometry)!
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)

Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.fm.assignment.core.dao.PlaceRepository.findLocationWithin(com.vividsolutions.jts.geom.Geometry)!
        at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:92)
        at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:62)

Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: PlaceEntity is not mapped [select l from PlaceEntity l where within(l.location, :filter) = true]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: PlaceEntity is not mapped [select l from PlaceEntity l where within(l.location, :filter) = true]
        at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:96)
        at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:120)

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: PlaceEntity is not mapped
        at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189)
        at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)
        at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:95)

Y a-t-il une erreur dans ma configuration ?

1voto

Nico Van Belle Points 2553

Vous avez nommé votre entité Lieu ( @Entity(name = "Place") ) mais vous utilisez toujours PlaceEntity dans votre requête jpql.

Essayez comme ça ;

select l from Place l where within(l.location, :filter) = true

Ou continuer à utiliser PlaceEntity dans vos requêtes et utilisez les annotations suivantes ;

@Data
@Entity
@Table(name ="Place")
public class PlaceEntity extends BaseEntity {}

1voto

panser Points 599

À l'avenir, utiliser des variables dans les dépôts de spring-data-jpa comme #{#entityName} pour vous protéger de telles erreurs

@Query("select l from #{#entityName} l where within(l.location, :filter) = true")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X