spring 找不到能够从类型转换到类型的转换器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46083329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
No converter found capable of converting from type to type
提问by Menios
I am getting the following stacktrace:
我得到以下堆栈跟踪:
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [referencedata.ABDeadlineType] to type [referencedata.DeadlineType]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:324)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:206)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:187)
at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:256)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:201)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:212)
at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:149)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:121)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
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)
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.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy143.findAllSummarizedBy(Unknown Source)
at
My classes are the following
我的课程如下
DeadlineType
截止日期类型
@Data
public class DeadlineType extends DefaultIdAndText {
@Value("#{target.id}")
String id;
@Value("#{target.code}")
String text;
@Value("#{target.id}")
public String getId() {
return id;
}
@Value("#{target.code}")
public String getText() {
return text;
}
}
ABDeadlineType
AB截止日期类型
@Data
@Entity
@Table(name = "deadline_type")
@AllArgsConstructor
@NoArgsConstructor
public class ABDeadlineType {
private @Id
String id;
private String code;
}
DefaultIdAndText
默认标识和文本
@Data @AllArgsConstructor
@NoArgsConstructor
public class DefaultIdAndText implements IdAndText {
public DefaultIdAndText(IdAndText idAndText){
this.id = idAndText.getId();
this.text = idAndText.getText();
}
@NotEmpty String id;
String text;
}
DeadlineTypeRepository
截止日期类型存储库
public interface DeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
List<DeadlineType> findAllSummarizedBy();
}
Update
更新
Could it be an issue that the projection/mapping using @Value("#{target.id}")format, does not work correctly because these have been done on a class and not on an interface???
使用@Value("#{target.id}")格式的投影/映射无法正常工作是否可能是一个问题,因为这些是在类上而不是在接口上完成的???
回答by Nick Savenia
Return ABDeadlineTypefrom repository:
ABDeadlineType从存储库返回:
public interface ABDeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
List<ABDeadlineType> findAllSummarizedBy();
}
and then convert to DeadlineType. Manually or use mapstruct.
然后转换为 DeadlineType。手动或使用 mapstruct。
Or call constructor from @Queryannotation:
或者从@Query注解调用构造函数:
public interface DeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
@Query("select new package.DeadlineType(a.id, a.code) from ABDeadlineType a ")
List<DeadlineType> findAllSummarizedBy();
}
Or use @Projection:
或使用@Projection:
@Projection(name = "deadline", types = { ABDeadlineType.class })
public interface DeadlineType {
@Value("#{target.id}")
String getId();
@Value("#{target.code}")
String getText();
}
Update:Spring can work without @Projectionannotation:
更新:Spring 可以在没有@Projection注释的情况下工作:
public interface DeadlineType {
String getId();
String getText();
}
回答by Les Wilson
You may already have this working, but the I created a test project with the classes below allowing you to retrieve the data into an entity, projection or dto.
您可能已经有了这个工作,但是我使用下面的类创建了一个测试项目,允许您将数据检索到实体、投影或 dto 中。
Projection- this will return the code column twice, once named code and also named text (for example only). As you say above, you don't need the @Projection annotation
投影- 这将返回代码列两次,一次命名为代码,也命名为文本(仅作为示例)。正如你上面所说,你不需要@Projection 注释
import org.springframework.beans.factory.annotation.Value;
public interface DeadlineTypeProjection {
String getId();
// can get code and or change name of getter below
String getCode();
// Points to the code attribute of entity class
@Value(value = "#{target.code}")
String getText();
}
DTO class- not sure why this was inheriting from your base class and then redefining the attributes. JsonProperty just an example of how you'd change the name of the field passed back to a REST end point
DTO 类- 不知道为什么这是从您的基类继承然后重新定义属性。JsonProperty 只是一个示例,说明如何更改传递回 REST 端点的字段名称
import com.fasterxml.Hymanson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class DeadlineType {
String id;
// Use this annotation if you need to change the name of the property that is passed back from controller
// Needs to be called code to be used in Repository
@JsonProperty(value = "text")
String code;
}
Entity class
实体类
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Data
@Entity
@Table(name = "deadline_type")
public class ABDeadlineType {
@Id
private String id;
private String code;
}
Repository- your repository extends JpaRepository<ABDeadlineType, Long> but the Id is a String, so updated below to JpaRepository<ABDeadlineType, String>
存储库- 您的存储库扩展 JpaRepository<ABDeadlineType, Long> 但 Id 是一个字符串,因此在下面更新为 JpaRepository<ABDeadlineType, String>
import com.example.demo.entity.ABDeadlineType;
import com.example.demo.projection.DeadlineTypeProjection;
import com.example.demo.transfer.DeadlineType;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ABDeadlineTypeRepository extends JpaRepository<ABDeadlineType, String> {
List<ABDeadlineType> findAll();
List<DeadlineType> findAllDtoBy();
List<DeadlineTypeProjection> findAllProjectionBy();
}
Example Controller- accesses the repository directly to simplify code
Example Controller- 直接访问存储库以简化代码
@RequestMapping(value = "deadlinetype")
@RestController
public class DeadlineTypeController {
private final ABDeadlineTypeRepository abDeadlineTypeRepository;
@Autowired
public DeadlineTypeController(ABDeadlineTypeRepository abDeadlineTypeRepository) {
this.abDeadlineTypeRepository = abDeadlineTypeRepository;
}
@GetMapping(value = "/list")
public ResponseEntity<List<ABDeadlineType>> list() {
List<ABDeadlineType> types = abDeadlineTypeRepository.findAll();
return ResponseEntity.ok(types);
}
@GetMapping(value = "/listdto")
public ResponseEntity<List<DeadlineType>> listDto() {
List<DeadlineType> types = abDeadlineTypeRepository.findAllDtoBy();
return ResponseEntity.ok(types);
}
@GetMapping(value = "/listprojection")
public ResponseEntity<List<DeadlineTypeProjection>> listProjection() {
List<DeadlineTypeProjection> types = abDeadlineTypeRepository.findAllProjectionBy();
return ResponseEntity.ok(types);
}
}
Hope that helps
希望有帮助
Les
莱斯
回答by Sangam Belose
If you look at the exception stack trace it says that, it failed to convert from ABDeadlineTypeto DeadlineType. Because your repository is going to return you the objects of ABDeadlineType. How the spring-data-jpawill convert into the other one(DeadlineType). You should return the same type from repository and then have some intermediate util class to convert it into your model class.
如果您查看异常堆栈跟踪,它说,它无法从 转换ABDeadlineType为DeadlineType。因为您的存储库将返回ABDeadlineType. 将如何spring-data-jpa转换为另一个(DeadlineType)。您应该从存储库返回相同的类型,然后使用一些中间 util 类将其转换为您的模型类。
public interface ABDeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
List<ABDeadlineType> findAllSummarizedBy();
}

