如何解决为什么手动创建时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 举报,一经查实,本站将立刻删除。