微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么手动创建时Specification-arg-resolver联接别名不起作用?

如何解决为什么手动创建时Specification-arg-resolver联接别名不起作用?

我的应用程序和端到端测试运行良好,它们通过db中的标签找到合适的项目。 我在基于控制器层注解的specification-arg-resolver中使用它来轻松处理具有许多参数的请求并为我创建规范。 问题出在我手动创建规范的@DataJpaTest类中。使用联接的测试在此失败:

Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [pt] on this ManagedType [com.tbar.makeupstoreapplication.model.Product]
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.checkNotNull(AbstractManagedType.java:147)
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:118)
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:43)
at org.hibernate.query.criteria.internal.path.AbstractFromImpl.locateAttributeInternal(AbstractFromImpl.java:111)
at org.hibernate.query.criteria.internal.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:204)
at org.hibernate.query.criteria.internal.path.AbstractPathImpl.get(AbstractPathImpl.java:177)
at net.kaczmarzyk.spring.data.jpa.domain.PathSpecification.path(PathSpecification.java:50)
at net.kaczmarzyk.spring.data.jpa.domain.In.toPredicate(In.java:59)
at net.kaczmarzyk.spring.data.jpa.domain.EmptyResultOnTypeMismatch.toPredicate(EmptyResultOnTypeMismatch.java:55)
at net.kaczmarzyk.spring.data.jpa.domain.Conjunction.toPredicate(Conjunction.java:80)
at net.kaczmarzyk.spring.data.jpa.domain.Conjunction.toPredicate(Conjunction.java:80)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.applySpecificationToCriteria(SimpleJpaRepository.java:762)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:693)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:651)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:443)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:371)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:204)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:657)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:621)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)

失败的测试如下:

@Test
void shouldFindProductWithTag() {
    Product expectedProduct = createProductWithTags(1L,"ProperTag");
    productRepository.save(expectedProduct);

    Specification<Product> specification = createSpecWithTag("ProperTag");
    Pageable pageable = PageRequest.of(0,12);

    Page<Product> actualPageOfProducts = productRepository.findAll(specification,pageable);

    assertEquals(expectedProduct,actualPageOfProducts.getContent().get(0));
}
private Conjunction<Product> createSpecWithTag(String... tagName) {
    return new Conjunction<>(createJoin("productTags","pt"),new Conjunction<>(createIn("pt.name",tagName)));
}

private Join<Product> createJoin(String pathToJoinOn,String alias) {
    return new Join<>(
            new WebRequestQueryContext(nativeWebRequestMock),pathToJoinOn,alias,JoinType.INNER,true);
}

private EmptyResultOnTypeMismatch<Product> createIn(String path,String[] expectedValue) {
    return new EmptyResultOnTypeMismatch<>(
            new In<>(
                    new WebRequestQueryContext(nativeWebRequestMock),path,expectedValue,Converter.withTypeMismatchBehavIoUr(OnTypeMismatch.EMPTY_RESULT)));
}

我从实际的工作应用程序的调试过程中复制了 createSpecWithTags 私有方法的结构,其中,规范的toString方法看起来像这样:

连接词[innerSpecs = [Join [pathToJoinOn = productTags,别名= pt,joinType = INNER,queryContext = WebRequestQueryContext [contextMap = {}],distinguiq = true],连接词[innerSpecs = [EmptyResultOnTypeMismatch [wrappedSpec = net.kaczmarzyk。 spring.data.jpa.domain.In@90beeb55]]]]]

型号

@Entity
@Table
@Data
@NoArgsConstructor
public class Product {

    @Id
    private Long id;
    @OnetoMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinColumn(name = "PRODUCT_ID")
    private Set<ProductTag> productTags;
}
@Entity
@Table
@Data
@NoArgsConstructor
@requiredArgsConstructor
public class ProductTag {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @EqualsAndHashCode.Exclude
    private int id;
    @NonNull
    private String name;
}

存储库

public interface ProductRepository extends JpaRepository<Product,Long> {

    Page<Product> findAll(Specification<Product> specification,Pageable pageable);
}

控制器方法

@GetMapping
    public String shopPage(Model model,@Join(path = "productTags",alias = "pt")
        @And({
            @Spec(path = "pt.name",params = "product_tags",spec = In.class)
    }) Specification<Product> productSpecification,Pageable pageable) throws ProductsNotFoundException {
        Page<Product> pageOfProducts = makeupService.findProducts(productSpecification,pageable);
        addAttributesToShopModel(model,pageOfProducts);
        return ViewNames.SHOP;
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。