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$1.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$1.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
期限タイプ
@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
@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();
}
@Value("#{target.id}")
形式を使用した投影/マッピングがインターフェイスではなくクラスで行われたため、正しく機能しないという問題がありますか?
リポジトリからABDeadlineType
を返します:
public interface ABDeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
List<ABDeadlineType> findAllSummarizedBy();
}
次に、DeadlineTypeに変換します。手動で、またはmapstructを使用します。
または、@Query
アノテーションからコンストラクターを呼び出します。
public interface DeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
@Query("select new package.DeadlineType(a.id, a.code) from ABDeadlineType a ")
List<DeadlineType> findAllSummarizedBy();
}
または、@Projection
を使用します。
@Projection(name = "deadline", types = { ABDeadlineType.class })
public interface DeadlineType {
@Value("#{target.id}")
String getId();
@Value("#{target.code}")
String getText();
}
更新: Springは@Projection
アノテーションなしで機能します:
public interface DeadlineType {
String getId();
String getText();
}
これはすでに機能しているかもしれませんが、以下のクラスでテストプロジェクトを作成し、データをエンティティ、プロジェクション、またはdtoに取得できるようにしました。
Projection-これはコード列を2回返します。コードに名前を付け、テキストにも名前を付けます(例のみ)。上記のように、@ 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-これが基本クラスから継承し、属性を再定義した理由がわかりません。 JsonPropertyは、RESTエンドポイントに戻されるフィールドの名前を変更する方法の単なる例です
import com.fasterxml.jackson.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;
}
エンティティクラス
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;
}
リポジトリ-リポジトリは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();
}
コントローラの例-リポジトリに直接アクセスしてコードを簡素化
@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);
}
}
役立つことを願っています
レ
例外スタックトレースを見ると、ABDeadlineType
からDeadlineType
への変換に失敗していることがわかります。リポジトリはABDeadlineType
のオブジェクトを返すためです。 spring-data-jpa
が他のものに変換される方法(DeadlineType
)。リポジトリから同じ型を返してから、中間クラスを使用してモデルクラスに変換する必要があります。
public interface ABDeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
List<ABDeadlineType> findAllSummarizedBy();
}