ConversionNotSupportedException通过Spring引导中的服务使用@IdClass主键保存jpa实体

时间:2018-03-28 11:48:26

标签: java jpa spring-boot service spring-data

尝试使用@IdClass主键保存JPA实体时出现奇怪的错误。使用测试并将实体直接保存到存储库可以在不涉及事务的情况下工作,但在通过服务时会抛出错误。

org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'xxx.yyy.model.entity.TournamentEntity_$$_jvstffa_0' to required type 'java.lang.String' for property 'tournament'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'xxx.yyy.model.entity.TournamentEntity_$$_jvstffa_0' to required type 'java.lang.String' for property 'tournament': no matching editors or conversion strategy found

    at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590)
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604)
    at org.springframework.beans.AbstractNestablePropertyAccessor.processLocalProperty(AbstractNestablePropertyAccessor.java:453)
    at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:278)
    at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:246)
    at org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper.setPropertyValue(DirectFieldAccessFallbackBeanWrapper.java:75)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation$IdentifierDerivingDirectFieldAccessFallbackBeanWrapper.setPropertyValue(JpaMetamodelEntityInformation.java:340)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.getId(JpaMetamodelEntityInformation.java:166)
    at org.springframework.data.repository.core.support.AbstractEntityInformation.isNew(AbstractEntityInformation.java:42)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.isNew(JpaMetamodelEntityInformation.java:232)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:489)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:377)
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:629)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:593)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy114.save(Unknown Source)
    at xxx.yyy.service.TournamentService.createParty(TournamentService.java:104)

我的TournamentEntity课程如下所示:

@Entity
@Table(name = "TOURNAMENT")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TournamentEntity {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @Column(name = "ID")
    private String id;

    @OneToMany(mappedBy = "tournament", cascade = ALL)
    List<PartyEntity> parties;
}

我的PartyEntity类看起来像是这样的问题:

@Entity
@Table(name = "PARTY")
@ToString(exclude = "tournament")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@IdClass(PartyId.class)
public class PartyEntity {

    @Id
    @ManyToOne
    @JoinColumn(name = "TOURNAMENT_ID", referencedColumnName = "ID", insertable = false, updatable = false)
    private TournamentEntity tournament;

    @Id
    @Column(name = "PARTY_ID", insertable = false, updatable = false)
    private String partyId;

    @Enumerated(value = EnumType.STRING)
    @NotNull
    private PartyState state;
}

持有主键的PartyId类看起来像这样,这就是映射似乎失败的地方:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PartyId implements Serializable {
    private String tournament;
    private String partyId;
}

在TournamentService类中,save会抛出异常:

@Transactional
public PartyEntityDTO createParty(String tournamentId) {
    TournamentEntity tournament = tournamentRepository.getOne(tournamentId);
    PartyEntity party = tournamentPartyRepository.save(PartyEntity.builder().tournament(tournament).state(REGISTERED).partyId(UUID.randomUUID().toString()).build());
    return modelMapper.map(party, PartyEntityDTO.class);
}

然而,使用存储库直接工作完全正常。运行以下测试会将Party添加到数据库中。不涉及周围的交易注释

@RunWith(SpringRunner.class)
@SpringBootTest
//@Transactional
public class PartyDatabaseTest {

    @Autowired
    private TournamentPartyRepository partyRepository;

    @Autowired
    private TournamentRepository tournamentRepository;

        @Test
        public void testInsertEntry() {
            TournamentEntity loadedTournament = tournamentRepository.findAll().get(0);
            PartyEntity party = partyRepository
                    .save(PartyEntity
                            .builder()
                            .tournament(loadedTournament)
                            .partyId(UUID.randomUUID().toString())
                            .state(REGISTERED)
                            .build());
        }
}

对于我做错的任何建议都将不胜感激!

0 个答案:

没有答案