Hibernate复合外键因生成的ID而失败

时间:2018-08-23 15:20:09

标签: java mysql hibernate jpa spring-data-jpa

我创建了一个简单的示例程序,显示了我的问题:
我有一个拥有n个所有者(1至n)的国家,
 主人有一只狗(1对1),
所有现实都在确定关系。
我正在使用MySql并且设置了'spring.jpa.hibernate.ddl-auto = create'
在我的application.properties文件中,因此将自动生成databaseTables。

国家/地区:

  
  @Entity
@Table(name = "country")
@Data  
public class Country {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column
    private String name;

    @OneToMany(mappedBy = "countryId",cascade = CascadeType.ALL)
    private Collection<Owner> owners;

    public Country() {
    }
}  

所有者:

    @Entity
@Table(name = "owner")  
@IdClass(OwnerId.class)  
@Data  
public class Owner {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;


    @Id
    @JoinColumn(name = "country_id")
    @Column(name = "country_id")
    private long countryId;


    @Column
    private String name;

    @OneToOne(mappedBy = "owner",cascade = CascadeType.ALL)
    private Dog dog;


    public Owner() {
    }
}  

狗:

 @Entity
@Data  
@Table(name = "dog")  
@IdClass(DogId.class)  
public class Dog {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column
    private String name;

    @OneToOne
    @JoinColumns({
            @JoinColumn(name = "owner_id",referencedColumnName = "id",insertable = false,updatable = false),
            @JoinColumn(name = "owner_country_id",referencedColumnName = "country_id",insertable = false,updatable = false)
    })
    @JsonIgnore
    private Owner owner;


    @Id
    @Column(name = "owner_id")
    private long owner_id;

    @Id
    @Column(name = "owner_country_id")
    private long owner_country_id;

    public Dog() {
    }
}

IdClasses:

@Data  
public class DogId implements Serializable {  
    private long id;  
    private long owner_id;  
    private long owner_country_id;  

public DogId(long id, long owner_id, long owner_country_id) {
    this.id = id;
    this.owner_id = owner_id;
    this.owner_country_id = owner_country_id;
}

public DogId() {
}


public boolean equals(Object o) {
    if ( this == o ) {
        return true;
    }
    if ( o == null || getClass() != o.getClass() ) {
        return false;
    }
    DogId pk = (DogId) o;
    return Objects.equals( id, pk.id ) &&
            Objects.equals( owner_id, pk.owner_id ) &&
            Objects.equals(owner_country_id,pk.owner_country_id);
}

@Override
public int hashCode() {
    return Objects.hash( id, owner_id, owner_country_id);
}


@Data  
public class OwnerId implements Serializable {  
    private long id;  
    private long countryId;  

public OwnerId(long id, long countryId) {
    this.id = id;
    this.countryId = countryId;
}

public OwnerId() {
}

public boolean equals(Object o) {
    if ( this == o ) {
        return true;
    }
    if ( o == null || getClass() != o.getClass() ) {
        return false;
    }
    OwnerId pk = (OwnerId) o;
    return Objects.equals( id, pk.id ) &&
            Objects.equals(countryId, pk.countryId);
}

@Override
public int hashCode() {
    return Objects.hash( id, countryId);
}

RestControllers:

    @org.springframework.web.bind.annotation.RestController
    @RequestMapping(value = "/api/country/{countryId}/owner")
    public class OwnerController {

        private OwnerRepository ownerRepository;

        @Autowired
        public OwnerController(OwnerRepository ownerRepository) {
            this.ownerRepository = ownerRepository;
        }

        @PostMapping(value = "/add")
        public ResponseEntity<Owner> addOwner(@RequestBody Owner owner,@PathVariable(value = "countryId") long countryId){
            owner.setCountryId(countryId);
        owner.getDog().setOwner_country_id(countryId);

        Owner dbOwner = ownerRepository.save(owner);
        //simple native sql update query
        dogRepository.updateDogsOwnerId(dbOwner.getId(),  
            dbOwner.getDog().getId());
        return ResponseEntity.ok(dbOwner);
        }

        @DeleteMapping(value = "/{ownerId}/delete")
        public ResponseEntity deleteOwner(@PathVariable(value = "ownerId") long ownerId,@PathVariable(value = "countryId") long countryId){
            OwnerId ownerKey = new OwnerId(ownerId,countryId);
            ownerRepository.deleteById(ownerKey);
            return ResponseEntity.ok().build();
        }

    }  

@RestController
@RequestMapping(value = "/api/country/")
public class CountryController {
    @Autowired
    private CountryRepository countryRepository;

    @PostMapping("add")
    public ResponseEntity<Country> addCountry(@RequestBody Country country){
        try {
            return ResponseEntity.ok(countryRepository.save(country));
        }catch (Exception e){
            System.err.println(e.getMessage());
            return ResponseEntity.badRequest().build();
        }
    }

    @DeleteMapping("/{countryId}/delete")
    public ResponseEntity deleteCountry(@PathVariable(value = "countryId") long countryId){
        try {
            countryRepository.deleteById(countryId);
            return ResponseEntity.ok().build();
        }catch (Exception e){
            System.err.println(e.getMessage());
            return ResponseEntity.badRequest().build();
        }
    }
}

在测试中,我将创建并添加这样的实体:

@Test
    public void testAddOwner() {
        Country country = new Country();
        country.setName("ExampleCountry");

        ResponseEntity<Country> responseEntity = restTemplate.postForEntity(URL+port+"/api/country/add", country,Country.class);
        Assert.assertTrue(responseEntity.getStatusCode().is2xxSuccessful());

        countryId = responseEntity.getBody().getId();
        Owner owner = new Owner();
        owner.setName("Vince");


        Dog dog = new Dog();
        dog.setName("Bello");


        //owner.setCountryId(countryId);  not needed
        owner.setDog(dog);


        List<Owner> owners = new ArrayList<>(1);
        owners.add(owner);

        ResponseEntity<Owner> ownerResponseEntity = restTemplate.postForEntity(URL+port+"/api/country/"+ countryId +"/owner/add",owner,Owner.class);
        Assert.assertTrue(ownerResponseEntity.getStatusCode().is2xxSuccessful());  
}

添加所有者时,此测试通过以下堆栈跟踪失败:

java.lang.IllegalArgumentException: Can not set long field com.gilbaul.testdb.OwnerId.id to org.hibernate.id.IdentifierGeneratorHelper$2
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:1.8.0_181]
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:1.8.0_181]
    at sun.reflect.UnsafeLongFieldAccessorImpl.set(UnsafeLongFieldAccessorImpl.java:102) ~[na:1.8.0_181]
    at java.lang.reflect.Field.set(Field.java:764) ~[na:1.8.0_181]
    at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:41) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:434) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:97) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:105) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.jpa.event.internal.core.JpaMergeEventListener.saveWithGeneratedId(JpaMergeEventListener.java:56) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:255) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:235) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:301) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:170) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:884) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:870) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350) ~[spring-orm-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at com.sun.proxy.$Proxy107.merge(Unknown Source) ~[na:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:305) ~[spring-orm-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at com.sun.proxy.$Proxy107.merge(Unknown Source) ~[na:na]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:493) ~[spring-data-jpa-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:377) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:629) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:593) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135) ~[spring-data-jpa-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at com.sun.proxy.$Proxy112.save(Unknown Source) ~[na:na]
    at com.gilbaul.testdb.OwnerController.addOwner(OwnerController.java:25) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.32.jar:8.5.32]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]  

不能通过反射来设置OwnerId复合键的id字段。 但是,如果我使狗和主人的ID 不是生成的值,
并在测试中手动设置ID,一切正常。
注意:在每个类中,用实际的Getter和Setter替换@Data时,该程序的行为相同。

它为什么会这样,我该如何使用自动产生的ID进行这项工作?

1 个答案:

答案 0 :(得分:0)

我通过使用另一种“生成价值策略”使它起作用。
不太满意,因为我仍然不确定身份策略的问题是什么。

    @Entity
    @Table(name = "dog")
    @IdClass(DogId.class)
    public class Dog {

        @TableGenerator(
                name="dogGen",
                allocationSize=1)
        @Id
        @GeneratedValue(strategy = GenerationType.TABLE, generator = "dogGen")
        private long id;
    ...  
    }


    @Entity
    @Table(name = "owner")
    @IdClass(OwnerId.class)
    public class Owner {


        @TableGenerator(
                name="ownerGen",
                allocationSize=1)
        @Id
        @GeneratedValue(strategy = GenerationType.TABLE,generator = "ownerGen")
        @Column(name = "id")
        private long id;
    ...
    }

这可以与ForeignKey IdClasses配合使用。
也许它可以帮助某人在类似问题上之以鼻。