无法使用Spring JpaRepository持久保存数据

时间:2019-11-06 09:15:03

标签: java hibernate spring-data-jpa

我已经创建了一个简单的3实体数据模型,并且在尝试保留数据时无法正常工作。 这是服务器的实体及其ID类:

@Entity
@Data
public class Server {

    @Id
    private String name;

    private String serverUrl;

    @OneToMany(mappedBy = "server", fetch = FetchType.LAZY)
    private List<Service> services;
}

服务:

@Entity
@IdClass(ServiceId.class)
public class Service {

    @Id
    private String name;

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    private Server server;

    @OneToMany(mappedBy = "service", fetch = FetchType.EAGER)
    private List<Container> containers;
}

public class ServiceId implements Serializable {

    private String name;

    private Server server;
}

容器:

@Entity
@IdClass(ContainerId.class)
public class Container {

    @Id
    private String name;

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    private Service service;

    private String command;
    private String state;
    private String ports;
}

@Data
public class ContainerId implements Serializable {

    private String name;

    private Service service;
}

我正在尝试使用ServiceRepository:

public interface ServiceRepository extends JpaRepository<Service, ServiceId>    {
}

保留服务对象:

public class SomeClass{

    @Autowired
    ServiceRepository serviceRepository;

    @Transactional
    public void insertServices(Service service) {
        serviceRepository.save(service); <- Exception HERE!
    }
}

服务对象包含一个已经在服务器表中的数据库中的服务器,一个不在数据库中的服务本身,以及一个不在数据库中的容器列表(并且现在也应保持不变)。 这样做时出现的错误是:

  

org.springframework.beans.ConversionNotSupportedException:无法将类型“ java.lang.String”的属性值转换为属性“ server”的必需类型“ a.servers.Server”;嵌套异常为java.lang.IllegalStateException:无法将类型“ java.lang.String”的值转换为属性“ server”的必需类型“ a.servers.Server”:未找到匹配的编辑器或转换策略       在org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590)〜[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604)〜[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.beans.AbstractNestablePropertyAccessor.processLocalProperty(AbstractNestablePropertyAccessor.java:453)〜[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:278)〜[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:246)〜[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper.setPropertyValue(DirectFieldAccessFallbackBeanWrapper.java:75)〜[spring-data-commons-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation $ IdentifierDerivingDirectFieldAccessFallbackBeanWrapper.setPropertyValue(JpaMetamodelEntityInformation.java:358)〜[spring-data-jpa-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.getId(JpaMetamodelEntityInformation.java:166)〜[spring-data-jpa-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.data.repository.core.support.AbstractEntityInformation.isNew(AbstractEntityInformation.java:42)〜[spring-data-commons-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.isNew(JpaMetamodelEntityInformation.java:237)〜[spring-data-jpa-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:553)〜[spring-data-jpa-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)〜[na:1.8.0_172]       在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)〜[na:1.8.0_172]       在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)〜[na:1.8.0_172]       在java.lang.reflect.Method.invoke(Method.java:498)〜[na:1.8.0_172]       在org.springframework.data.repository.core.support.RepositoryComposition $ RepositoryFragments.invoke(RepositoryComposition.java:371)〜[spring-data-commons-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:204)〜[spring-data-commons-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.data.repository.core.support.RepositoryFactorySupport $ ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:657)〜[spring-data-commons-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:621)〜[spring-data-commons-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605)〜[spring-data-commons-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)〜[spring-data-commons-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:353)〜[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)〜[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)〜[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor $ CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178)〜[spring-data-jpa-2.2.0.RELEASE.jar:2.2.0.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在com.sun.proxy。$ Proxy96.save(未知来源)〜[na:na]       在a.services.ServiceService.updateServices(ServiceService.java:20)〜[classes /:na]       在a.services.ServiceService $$ FastClassBySpringCGLIB $$ 7cf24811.invoke()〜[classes /:na]       在org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)〜[spring-core-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.proceed(CglibAopProxy.java:747)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:353)〜[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)〜[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.proceed(CglibAopProxy.java:747)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)〜[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在a.services.ServiceService $$ EnhancerBySpringCGLIB $$ a987bcb2.updateServices()〜[classes /:na]       在a.agents.DataFetcher.fetch(DataFetcher.java:48)〜[classes /:na]       在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)〜[na:1.8.0_172]       在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)〜[na:1.8.0_172]       在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)〜[na:1.8.0_172]       在java.lang.reflect.Method.invoke(Method.java:498)〜[na:1.8.0_172]       在org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)〜[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)〜[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)上[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511)[na:1.8.0_172]       在java.util.concurrent.FutureTask.run $$$ capture(FutureTask.java:266)[na:1.8.0_172]       在java.util.concurrent.FutureTask.run(FutureTask.java)处[na:1.8.0_172]       在java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 201(ScheduledThreadPoolExecutor.java:180)[na:1.8.0_172]       在java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)[na:1.8.0_172]       在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)[na:1.8.0_172]       在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624)[na:1.8.0_172]       在java.lang.Thread.run(Thread.java:748)[na:1.8.0_172]   原因:java.lang.IllegalStateException:无法将属性“ server”的类型“ java.lang.String”的值转换为所需的类型“ a.servers.Server”:未找到匹配的编辑器或转换策略       在org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:262)〜[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]       在org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:585)〜[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]       ...省略了62个共同的框架

我在application.yml中将spring-> jpa-> show-sql设置为true,因此在失败之前我会收到此日志:

  

休眠:从服务器server0_中选择server0_.name作为name1_1_,选择server0_.server_url作为server_u2_1 _

创建的数据库似乎没问题:

DB Scheme

1 个答案:

答案 0 :(得分:0)

我在当前项目中也遇到了类似的组合键问题。
也许我错了,但是对我来说,@IdClass仅在没有@Id注释的属性是外键的情况下才有效。 最后,我改为使用@EmbeddedId重构了实体。

...

实际上我还有一个主意:尝试在@ManyToOne类的server属性中添加ServiceId批注:

public class ServiceId implements Serializable {

    private String name;

    @OneToMany(mappedBy = "service", fetch = FetchType.EAGER)
    private Server server;
}