После обновления @MapsId выдает ошибку при сохранении существующего объекта, но в остальном работает нормально - PullRequest
0 голосов
/ 25 октября 2019

Я работаю над обновлением проекта Spring Boot 1.5.21 (Java 8u221) до Spring Boot 2.1.9 (Java 11.0.2-open) . В обоих случаях мы используем сборку gradle с загрузчиками Spring и средством разрешения зависимостей, поэтому версии базовых библиотек Spring, JPA и Hibernate управляются пружинами.

В проекте имеется дополнительный одноадресныйодно отображение, в котором дочерняя сущность получает свой идентификатор из сгенерированного идентификатора родителя. В версии проекта Spring Boot 1 отношение было настроено так:

@Entity
@Table(name = "PARENT_OBJECT", schema = "MYSCHEMA")
public class ParentObject implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PARENT_OBJECT_ID_SEQ")
    @SequenceGenerator(name = "PARENT_OBJECT_ID_SEQ", sequenceName = "MYSCHEMA.PARENT_OBJECT_ID_SEQ")
    protected Long id;

    @OneToOne(optional = true, mappedBy = "parentObject", cascade = CascadeType.ALL, orphanRemoval = true)
    @Valid
    protected ChildObject childObject;

    // Other fields and methods
}

@Entity
@Table(name = "CHILD_OBJECT", schema = "MYSCHEMA")
public class ChildObject implements Serializable {
    @Id
    @Column(name = "parent_object_id", unique = true, nullable = false, insertable = true, updatable = false)
    private Long parentObjectId;

    @OneToOne
    @MapsId
    @PrimaryKeyJoinColumn
    @JsonIgnore
    private ParentObject parentObject;

    // Other fields and methods
}

Когда я обновился до Spring Boot 2 , мне пришлось обновитьмного настроек JPA, и одна особенность, на которую жаловались, была то, что сгенерированные запросы искали «PARENTOBJECT_ID» вместо «PARENT_OBJECT_ID», поэтому я немного разбирался в этом, нашел статью, объясняющую, как исправить имена столбцов длясопоставления «один к одному» с @JoinColumn и обновленные аннотации дочернего объекта для поля parentObject следующие:

@OneToOne
@MapsId
@JoinColumn(name = "parent_object_id")
@JsonIgnore
private ParentObject parentObject;

Я полностью удалил @PrimaryKeyJoinColumn, так как документация предполагает, что выследует использовать @MapsId, если вы хотите, чтобы Hibernate управлял назначением идентификаторов, и если вы собираетесь управлять ими самостоятельно, ЭТО, когда вы будете использовать @PrimaryKeyJoinColumn.

Эта конфигурация хорошо работала для всех моихтесты, кроме 2: интеграционные тесты UPDATE для контроллера (тесты POST работали отлично, когда создавался ParentObjectредактировал в первый раз вместе со связанным с ним ChildObject). Ошибка, которую я получаю только для этих двух тестов: :

org.springframework.orm.jpa.JpaSystemException: попытка назначить идентификатор из нулевого однозначного свойства [org.mycompany.myproject.mymodule.mysubmodule.ChildObject.parentObject];Вложенное исключение - org.hibernate.id.IdentifierGenerationException: попытка присвоить идентификатор из нулевого свойства «один к одному» [org.mycompany.myproject.mymodule.mysubmodule.ChildObject.parentObject]

Странная вещьявляется то, что все тесты интеграции репозитория для этих объектов и их ассоциаций проходят, а также все другие тесты интеграции контроллера, включая тот, где новый ParentObject POST поставлен с его новым ChildObject. Я искал возможное решение, но каждая статья, которую я читал, показала, что используемая конфигурация должна работать. Я также опробовал альтернативные конфигурации, в которых предлагались такие вещи, как @PrimaryKeyJoinColumn и установка поля идентификатора самостоятельно, с использованием генераторов идентификаторов по идентификатору ChildObject (хотя смысл @MapsId - указывать системе использовать идентификаторParentObject), и обычно я получаю больше неудачных тестов со следующей ошибкой:

org.springframework.orm.jpa.JpaSystemException: идентификаторы для этого класса должны быть вручнуюприсваивается перед вызовом save (): org.mycompany.myproject.mymodule.mysubmodule.ChildObject;вложенным исключением является org.hibernate.id.IdentifierGenerationException: идентификаторы для этого класса должны быть назначены вручную перед вызовом save (): org.mycompany.myproject.mymodule.mysubmodule.ChildObject

Хотя иногда я быполучить исходную ошибку невозможности «назначить идентификатор из нуля». На данный момент, Я в растерянности относительно того, как это настроено неправильно, или какой другой фактор связан с вещами . Я готов попробовать все и всякие предложения на данный момент.

Для полноты картины ниже приведено несколько фрагментов кода из приложения. Соответствующие номера строк из трассировки стека отмечены комментарием. Я опустил код контроллера, поскольку в этом нет ничего примечательного;оба метода POST и PUT вызывают один и тот же метод обслуживания;они просто находятся на разных конечных точках, и PUT сначала проверяет, существует ли объект в БД, прежде чем вызывать метод сохранения службы. Вот сервисный метод, который вызывает репозиторий JPA для ParentObject:

@Service
@Transactional(readOnly = true)
public class ParentObjectServiceImpl implements ParentObjectService {
    // other fields and other methods

    @Autowired
    private ParentObjectRepository parentObjectRepository;

    @Transactional(readOnly = false)
    @Override
    public ParentObject saveParentObject(final ParentObject parentObject) {
        parentObject.prepForPersistence();
        return parentObjectRepository.save(parentObject); //Line 93
    }
}

А вот мой репозиторий JPA:

public interface ParentObjectRepository extends CrudRepository<ParentObject, Long> {
    // custom methods, no override for save though
}

И вот prepForPersistence() метод ParentObject:

public void prepForPersistence() {
    if(childObject != null) {
        childObject.setParentObject(this);
        // In some iterations of the code in trying to solve this, I also had the following line
        //childObject.setParentObjectId(this.id);
    }
}

Вот два из тестов (один, который проходит, и другой, который не проходит):

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApplication.class)
@WebAppConfiguration
// This profile disabled csrf for testing, and sets some env variables
@ActiveProfiles("integration-test")
@Transactional
public class ParentObjectControllerTest {
    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.webAppContextSetup(context)
            .apply(springSecurity())
            .build();
    } 

    // This test PASSES
    @Test
    @WithMockUser(roles = {"MY_APP_ADMIN"}, username = TEST_USER)
    @Sql(scripts = "/db-scripts/bootstrap.sql")
    public void testPostParentObjectWithChildObject() {
        final ChildObject childObject = new ChildObject();
        // set some properties on childObject that don't relate to ParentObject

        final ParentObject parentObject = new ParentObject();
        // set some properties on parentObject that don't relate to ChildObject
        parentObject.setChildObject(childObject);

        final ParentObject result = given().mockMvc(mockMvc).contentType(ContentType.JSON)
            .and().body(item).log().all()
            .when().post("/parent-objects")
            .then().log().all().statusCode(201).contentType(ContentType.JSON)
            .and().body(matchesJsonSchemaInClasspath("json-schemas/parent-object.json"))
            .and().body("username", equalTo(TEST_USER))
            .extract().as(ParentObject.class);

        assertThat(result.getId(), is(notNullValue()));
        assertThat(result.getChildObject().getParentObjectId(), is(result.getId()));
    }

    // This test FAILS with the 'attempted to assign id from null one-to-one property' error
    @Test
    @WithMockUser(roles = {"MY_APP_ADMIN"}, username = TEST_USER)
    // Inserts a ParentObject record with ID -1
    @Sql(scripts = "/db-scripts/bootstrap.sql")
    public void testPutParentObjectWithChildObject() {
        final ChildObject childObject = new ChildObject();
        // set some properties on childObject that don't relate to ParentObject

        final Long EXISTING_ID = -1L;
        final ParentObject parentObject = new ParentObject();
        parentObject.setId(EXISTING_ID);
        parentObject.setChildObject(childObject);

        final ParentObject result = given().mockMvc(mockMvc).contentType(ContentType.JSON)
            .and().body(item).log().all()
            .when().put("/parent-objects/{parentObjectId}", parentObject.getId()) //line 260
            .then().log().all().statusCode(200)
            .extract().as(ParentObject.class);

        assertThat(result.getId(), is(EXISTING_ID));
        assertThat(result.getChildObject().getParentObjectId(), is(EXISTING_ID));
}

Вот полная трассировка стека:

Ответ с HTTPStatus = INTERNAL_SERVER_ERROR из-за следующей ошибки: org.springframework.orm.jpa.JpaSystemException: попытка присвоить идентификатор из нулевого свойства «один к одному» [org.mycompany.myproject.mymodule.mysubmodule.ChildObject.parentObject];вложенное исключение - org.hibernate.id.IdentifierGenerationException: попытка присвоить идентификатор из нулевого однозначного свойства [org.mycompany.myproject.mymodule.mysubmodule.ChildObject.parentObject] в org.springframework.orm.jpa.vendor.HibernateJpaDИсключениеorg.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible (ChainedPersistenceExceptionTranslator.java:61) в org.springframework.dao.support.DataAccessUtils.translateIfNePersistenceExceptionTranslationInterceptor.java:153) в org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:186) в org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor $ CrudMethodMetadataPopulatingMethodInterceptor.invoke (CrudMethodMetadataPostProcessor.java:144) в org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation. Java: 186) в org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor $ ExposeRepositoryInvocationInterceptor.invoke (CrudMethodMetadataPostProcessor.java:36hope).springframework.aop. .invoke (SurroundingTransactionDetectorMethodInterceptor.java: 61) в org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:186) в org.springframework.aop.framework.JdkDynamicAopProxy.invoke (joped.xyx.jpg)$ Proxy249.save (Неизвестный источник) по адресу org.mycompany.myproject.mymodule.ParentObjectServiceImpl.saveParentObject (ParentObjectServiceImpl.java:93) по адресу org.mycompany.myproject.mymodule.ParentObjectServiceImplIB36SFraSworkFragSignSignSignSigner.cglib.proxy.MethodProxy. .java: 163) в org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction (TransactionAspectSupport.java:295) в org.springframework.transaction.interceptor.TransactionInterceptor.invoke (TransactionInceptor0myproject.mymodule.ParentObjectServiceImpl $$ EnhancerBySpringCGLIB $$ d3a0c3ee.saveChecklistItem ()в org.mycompany.myproject.mymodule.ParentObjectController.putParentObject (ParentObjectController.java:78) в java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) в java.bot. invoke (NativeMethodAccessorImpl.java:62) в java.base / jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) в java.base / java.lang.reflect.jke.. по адресу org.springframework.web.method.support.InvocableHandlerMethod.doInvoke (InvocableHandlerMethod.java:190) по адресу org.springframework.web.method.support.InvocableHandlerMethod.inava.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle (ServletInvocableHandlerMethod.java:105) при org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod (RequestMappingHandlerAdapter.java:893) при org.springframework.web.servlet.mvc.method. DispatcherServlet.doDispatch (DispatcherServlet.java:1040) по адресу org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:943) по адресу org.springframework.web.servlet.FrameworkServ.let.web.springframework.web.servlet.FrameworkServlet.doPut (FrameworkServlet.java:920) в javax.servlet.http.HttpServlet.service (HttpServlet.java:668) в org.springframework.web.servlet.ralet.vlet: 883) в org.springframework.test.web.servlet.TestDispatcherServlet.service (TestDispatcherServlet.java:72) в javax.servlet.http.HttpServlet.service (HttpServlet.java:750) в org.springMockFilterChain $ ServletFilterProxy.doFilter (MockFilterChain.java: 167) по адресу org.springframework.mock.web.MockFilterChain.doFilter (MockFilterChain.java:134) по адресу org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (Filterava.rag: atraghain. security.web. intercept.FilterSecurityInterceptor.doFilter (FilterSecurityInterceptor.java:91) в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain. Java: 119) в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) в org.springframework.security.web.session.SessionManagementFilter.doFilter (SessionMan):org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) в org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter.doFava.web.security.prFilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) в org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter (SecurityContextHolderAwareRequestFililinha.haFFFF)Java: 334) в org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter (RequestCacheAwareFilter.java:63)в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) в org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter (Abstract.sb).FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) в org.sprint(LogoutFilter.java:116) в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) в org.springframework.web.filter.CorsFilter.doFilterInjag. Orgs (orors). springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119) в org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.jrag.spr. orf. at. web.header.HeaderWriterFilter.doFilterInternal (HeaderWriterFilter.java:74) в org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119) в org.springfilterFhaFFFFF.FirFirFile.File.File.File.File.File.File.File.File.File.File.File.File.File.File.File.File.File.File.File.RuJava: 334) в org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter (SecurityContextPersistenceFilter.java:105) в org.springframework.security.web.FilterChainProxy $ VirtualFilterCrain.Fraf.Fraf.Frag.Fraj.FF.jpg.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal (WebAsyncManagerIntegrationFilter.java:56) в org.springframework.web.filter.OncePerRequestFilter.doFilter:И$ VirtualFilterChain.doFilter (FilterChainProxy.java:334) в org.springframework.security.web.FilterChainProxy.doFilterInternal (FilterChainProxy.java:215) в org.springframework.security.web.FilterChainProxy.doFilter (FilterChainProxy.java:178) по адресу org.springframework.mock.web.MockFilterChain.doFilter (MockFilterChain.java:134) по адресу org.springframework.test.web.servlet.java.Mock.MockMC. ) в io.restassured.module.mockmvc.internal.MockMvcRequestSenderImpl.performRequest (MockMvcRequestSenderImpl.java:218) в io.restassured.module.mockmvc.internal.MockMvcRequest.enderImpl.jckmockmvc.internal.MockMvcRequestSenderImpl.put (MockMvcRequestSenderImpl.java:504) при io.restassured.module.mockmvc.internal.MockMvcRequestSenderImpl.put (MockMvcRequestSenderImpl.java:100) в org.mycompany.myproject.mymodule.ParentObjectControllerTest.testPutParentObjectWithChildObject (ParentObjectControllerTest. java: 260) в java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) в java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java.java. 62)internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) в java.base / java.lang.reflect.Method.invoke (Method.java:566) в org.junit.runners.model.Frameworkrjetlef Framework ($): 50) в org.junit.internal.runners.model.ReflectiveCallable.run (ReflectiveCallable.java:12) в org.junit.runners.model.FrameworkMethod.invokeExplosively (FrameworkMethod.java:47) в org.jit. runners.statements.InvokeMethod.evaluate (InvokeMethod.java:17) в org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate (RunBeforeTestExecutionCallbacks.java:74.conf.traf.extext.me) .teg. RunAfterTestExecutionCallbacks.evaluate (RunAfterTestExecutionCallbacks.java:84)в org.junit.internal.runners.statements.RunBefores.evaluate (RunBefores.java:26) в org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate (RunBeforeTestMethoj.sraback). ,(ParentRunner.java:325) в org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild (SpringJUnit4ClassRunner.java:251) в org.springframework.test.context.junit4.nerj.jj.RjJRNJRNC4CJRNC_RjS_RjS_RjS_RjS_RjS_RjS_RjS_RjS.Ru.Ru.Ru.Ru.Ru.Cn.Ru.Cn.Ru.Cn.Ru.Cn.Ru.Cn.Ru.Cj.Sjp. org.junit.runners.ParentRunner $ 3.run (ParentRunner.java:290) в org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:71) в org.junit.runners.ParentRunner.runChildren (ParentRun288) на org.junit.runners.ParentRunner.access $ 000 (ParentRunner.java:58) на org.junit. runners.ParentRunner $ 2.evaluate (ParentRunner.java:268) в org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate (RunBeforeTestClassCallbacks.java:61) в org.springfallstaA.Text.Text.Text.Text.TechЗначениеgradle.api.internal.tasks.testing.junit. gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute (JUnitTestClassExecutor.java:38) в org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor. gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass (SuiteTestClassProcessor.java:51) по адресу java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) по адресу java.base / jdk.internal.reflect.NativeMethodAccessorljava.base / jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) в java.base / java.lang.reflect.Method.invoke (Method.java:566) в org.gradle.inatch. ReflectionDispatch.dispatch (ReflectionDispatch.java:36) по адресу org.gradle.internal.dispatch.ReflectionDispatch.dispatch (ReflectionDispatch.java:24) по адресу org.gradle.internal.dispatch.ContextClassLoaderDispatch.disp.gradle.internal.dispatch.ProxyDispatchAdapter $ DispatchingInvocationHandler.invoke (ProxyDispatchAdapter.java:94) в com.sun.proxy. $ Proxy5.processTestClass (неизвестный источник) в org.gradle.api.internal.tasks.Tork.worker.processTestClass (TestWorker.java:118) в java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) в java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) в java.base / jdk.internal.rempho.Amphoid) в java.base / java.lang.reflect.Method.invoke (Method.java:566) в org.gradle.internal.dispatch.ReflectionDispatch.dispatch (ReflectionDispatch.java:36) в org.gradle.internal.dispatch. ReflectionDispatch.dispatch (ReflectionDispatch.java:24) в org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection $ DispatchWrapper.dispatch (MessageHubBackedObjectConnection.java:182)в org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection $ DispatchWrapper.dispatch (MessageHubBackedObjectConnection.java:164) в org.gradle.internal.remote.internal.hub.MessageHub $ Handler.java:HH сообщение (сообщениев org.gradle.internal.concurrent.ExecutorPolicy $ CatchAndRecordFailures.onExecute (ExecutorPolicy.java:64) в org.gradle.internal.concurrent.ManagedExecutorImpl $ 1.run (ManagedExecutorImpl.java:48) в java. concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1128) в java.base / java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:628) в org.gradle.internal.connableImptThreadFactoryImpl.java:56) в java.base / java.lang.Thread.run (Thread.java:834), вызванный: org.hibernate.id.IdentifierGenerationException: попытка присвоить идентификатор из нулевого однозначного свойства [org.mycompany.myproject.mymodule.mysubmodule.ChildObject.parentObject] at org.hibernate.id.ForeignGenerator.generate (ForeignGenerator.java:90) в org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId (AbstractSaveEventListener.java:119) в org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity:vent.venteventeventeventer.internal.DefaultMergeEventListener.entityIsTransient (DefaultMergeEventListener.java:259) в org.hibernate.event.internal.DefaultMergeEventListener.onMerge (DefaultMergeEventListener.java:191) в org.hibernate.java.inorg.hibernate.internal.SessionImpl.merge (SessionImpl.java:897) в org.hibernate.engine.spi.CascadingActions $ 6.cascade (CascadingActions.java:261) в org.hibernate.engine.internal.Cascade.cascadeToOne (Каскад.java: 490) в org.hibernate.engine.internal.Cascade.cascadeAssociation (Cascade.java:415) в org.hibernate.engine.internal.Cascade.cascadeProperty (Cascade.java:216) в org.hibernate.engine. internal.Cascade.cascade (Cascade.java:149) в org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge (DefaultMergeEventListener.java:532) в org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached (DefaultMergeEventListener.java:361) по умолчанию.Mergeв org.hibernate.event.internal.DefaultMergeEventListener.onMerge (DefaultMergeEventListener.java:72) в org.hibernate.internal.SessionImpl.fireMerge (SessionImpl.java:905) в org.hibernate.internal.SessionImpl.mer: 891) в java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (родной метод) в java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java.ink.in: 62).reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) в java.base / java.lang.reflect.Method.invoke (Method.java:566) в org.springframework.orm.jpa.SharedEntityManagerCreator $ SharedEntityManagerInvocationHandler.invoke (SharedEntityManagerCreator.java:310) в com.sun.proxy. $ Proxy214.merge (неизвестный источник) в org.springframework.data.jpa.repository.support.SimpleJpaRepository.save (SimpleJpaRepository.java:538) в java.base / jdk.internal.reflect. Java: 43) в java.base / java.lang.reflect.Method.invoke (Method.java:566) в org.springframework.data.repository.core.support.RepositoryComposition $ RepositoryFragments.invoke (RepositoryComposition.java:359)в org.springframework.data.repository.core.support.RepositoryComposition.invoke (RepositoryComposition.java:200) в org.springframework.data.repository.core.support.RepositoryFactorySupport $ ImplementMethodExecuoryFactoryInpp.Приятный_пакет.пункт_64). .springframework.aop.framework. .core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.lambda $ invoke $ 3 (RepositoryFactorySupport.java:595) по адресу org.springframework.data.repository.core.support.RepositoryFactory.execort.hopport_setup_setup_setup.exeaop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:186) в org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke (DefaultMethodInvokingMethodInterceptor.java:59) при org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:186) при org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction (TransactionAspectSupport.java:295) в орг.springframework.transaction.interceptor.TransactionInterceptor.invoke (TransactionInterceptor.java:98) в org.springframework.aop.framework. .java: 139) ... еще 140

Заранее спасибо за предложения и помощь!

1 Ответ

0 голосов
/ 25 октября 2019

Я думаю, что это ошибка, , но мне все еще интересны обходные пути, если у кого-то они есть . Первоначально в hibernate была обнаружена ошибка, которая, казалось, соответствовала этой проблеме, но она была зарегистрирована как затрагивающая только серию 5.2 и помеченная как «исправленная», и, поскольку наш проект использовал серию 5.3, я продолжил. Однако, копаясь в представленных ошибках с весенней стороны, след от хлебных крошек привел меня к этой ошибке серии 5.3: https://hibernate.atlassian.net/browse/HHH-13413, которая связана с ошибкой серии 5.2, которую я первоначально обнаружил, что, в отличие от записи 5.3казалось, предполагает, что это всегда было проблемой начиная с серии 5.2 и никогда не должно было работать в серии 5.3, потому что ошибка не только серии 5.3 была помечена как дубликат ошибки серии 5.2, когда я посмотрел поближе наВ версии 5.2 сообщалось, что версия исправления существовала только до версии 5.4: https://hibernate.atlassian.net/browse/HHH-12436

Так что я попытаюсь перейти на последнюю работающую серию 5.2 и обновить ее до версии 5.4 ... Я просто не уверен, как кто-то из них будет играть с остальной функциональностью Spring Data jpa и может быть большой проблемой само по себе.

Обновление: помимо столкновения с проблемой, потому что мы используем Java11 (https://hibernate.atlassian.net/browse/HHH-12924 -> Мне пришлось использовать javassist: 3.23.0-GA, чтобы получить hibernate-core: 5.2.13. Наконец-то, чтобы работать), понижение было успешным в получении tон один-к-одному снова работает. Все остальные тесты также пройдены. Однако я не проводил всестороннего тестирования с этим решением, так как предпочел бы решение на основе обновлений.

Обновление 2: смог обновиться до Spring Boot 2.2.0 (в котором используется Hibernate 5.4, которыйгде эта конкретная ошибка для сопоставлений один к одному была исправлена)! Это потребовало некоторых изменений в моих последовательностях, но не было слишком болезненным для обновления;даже не нужно было использовать флаг понижения! Если случайно ваша проблема с отображением не устранена, есть флаг «использовать поведение 5.2», так как они все еще обрабатывают изломы различных сценариев отображения. Более подробную информацию об этом смотрите в примечаниях по миграции на 5.4 здесь: https://github.com/hibernate/hibernate-orm/blob/61cddad76d5bba951805fa7ed90cc149d404841c/migration-guide.adoc

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...