Spring Data JDBC - один ко многим - Котлин - PullRequest
0 голосов
/ 05 декабря 2018

Я использую весеннюю загрузку 2.1.1.RELEASE и spring-data-jdbc 1.0.3.RELEASE, Kotlin 1.3.10.

У меня есть следующие простые определения классов в kotlin:

@Table(value = "CUSTOMER")
data class Customer(
    @Id
    var id: Long?,
    @Column("NAME")
    var name: String,
    @Column("PUBLICATION_NAME")
    var publicationName: String,
    @Column("START_DATE")
    var startDate: String,
    @Column("END_DATE")
    var endDate: String,

    var items: MutableSet<Item>

)

@Table(value = "ITEM")
data class Item  (
    @Id
    var id: Long?,
    @Column("name")
    var name: String,
    @Column("title")
    var title: String,
    @Column("weight")
    var weight: Double
)

И следующие определения таблиц базы данных:

CREATE TABLE customer(
  id                SERIAL PRIMARY KEY,
  name              VARCHAR(256) NOT NULL,
  publication_name  VARCHAR(128) NOT NULL,
  start_date        VARCHAR(10),
  end_date          VARCHAR(10)
);

CREATE TABLE item(
  id               SERIAL PRIMARY KEY,
  customer         INTEGER,
  name             VARCHAR(256)     NOT NULL,
  title            VARCHAR(128),
  weight           DOUBLE PRECISION NOT NULL
);

Я получаю следующую ошибку:

org.springframework.data.mapping.MappingException: Could not read property @org.springframework.data.annotation.Id()private java.lang.Long net.service.model.query.Item.id from result set!

    at org.springframework.data.jdbc.core.EntityRowMapper.readFrom(EntityRowMapper.java:130)
    at org.springframework.data.jdbc.core.EntityRowMapper.readEntityFrom(EntityRowMapper.java:143)
    at org.springframework.data.jdbc.core.EntityRowMapper.readFrom(EntityRowMapper.java:124)
    at org.springframework.data.jdbc.core.EntityRowMapper.lambda$createInstance$0(EntityRowMapper.java:167)
    at org.springframework.data.relational.core.conversion.BasicRelationalConverter$ConvertingParameterValueProvider.getParameterValue(BasicRelationalConverter.java:251)
    at org.springframework.data.convert.KotlinClassGeneratingEntityInstantiator$DefaultingKotlinClassInstantiatorAdapter.extractInvocationArguments(KotlinClassGeneratingEntityInstantiator.java:230)
    at org.springframework.data.convert.KotlinClassGeneratingEntityInstantiator$DefaultingKotlinClassInstantiatorAdapter.createInstance(KotlinClassGeneratingEntityInstantiator.java:204)
    at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84)
    at org.springframework.data.relational.core.conversion.BasicRelationalConverter.createInstance(BasicRelationalConverter.java:141)
    at org.springframework.data.jdbc.core.EntityRowMapper.createInstance(EntityRowMapper.java:160)
    at org.springframework.data.jdbc.core.EntityRowMapper.mapRow(EntityRowMapper.java:71)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:94)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:61)
    at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:679)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:694)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:748)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:235)
    at org.springframework.data.jdbc.core.DefaultDataAccessStrategy.findById(DefaultDataAccessStrategy.java:204)
    at org.springframework.data.jdbc.core.JdbcAggregateTemplate.findById(JdbcAggregateTemplate.java:135)
    at org.springframework.data.jdbc.repository.support.SimpleJdbcRepository.findById(SimpleJdbcRepository.java:66)
    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:359)
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    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:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:99)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy95.findById(Unknown Source)
    at net.service.model.query.repository.CustomerRepositoryV2Test.should save Customer with all Items(CustomerRepositoryV2Test.kt:24)
    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.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:515)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:171)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:167)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:114)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:59)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:105)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:71)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:110)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:71)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:110)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:71)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.h2.jdbc.JdbcSQLException: Column "items_id" not found [42122-197]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
    at org.h2.message.DbException.get(DbException.java:179)
    at org.h2.message.DbException.get(DbException.java:155)
    at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3148)
    at org.h2.jdbc.JdbcResultSet.get(JdbcResultSet.java:3247)
    at org.h2.jdbc.JdbcResultSet.getObject(JdbcResultSet.java:529)
    at org.springframework.data.jdbc.core.EntityRowMapper.readFrom(EntityRowMapper.java:127)
    ... 88 more

Из исходной документации: "Таблица ссылочной сущностиожидается, что дополнительный столбец будет называться так же, как и таблица ссылочной сущности. Вы можете изменить это имя, реализовав NamingStrategy.getReverseColumnName (свойство RelationalPersistentProperty). "

Что я делаю не так?

Обновление: добавление коллекции наборов java не также помогло:

var items: java.util.HashSet<Item> = java.util.HashSet()

Обновление 2: по-прежнему не исправлено, добавлен воспроизводимый пример проекта на github:

https://github.com/ielkhalloufi/spring-data-jdbc-example

Ответы [ 3 ]

0 голосов
/ 07 января 2019

Попробуйте переместить набор из конструктора в тело как

@Table(value = "CUSTOMER")
data class Customer(
    @Id
    var id: Long?,
    @Column("NAME")
    var name: String,
    @Column("PUBLICATION_NAME")
    var publicationName: String,
    @Column("START_DATE")
    var startDate: String,
    @Column("END_DATE")
    var endDate: String
){
    var items: MutableSet<Item> = HashSet()
}

И отредактируйте свой тест как

val gasLineItem = Customer(
            id = null,
            name = "name",
            publicationName = "",
            startDate = "2018-12-01",
            endDate = "2019-02-01"

    ).apply {
        items = mutableSetOf(
                gasCreative1,
                gasCreative2
        )
    }
0 голосов
/ 15 февраля 2019

Вы также можете использовать @PersistenceConstructor для явного указания Spring Data JDBC на конструктор, который не включает Set (что является причиной ошибки).Например:

@Table(value = "CUSTOMER")
data class Customer(
    @Id
    var id: Long?,
    @Column("NAME")
    var name: String,
    @Column("PUBLICATION_NAME")
    var publicationName: String,
    @Column("START_DATE")
    var startDate: String,
    @Column("END_DATE")
    var endDate: String,
    var items: MutableSet<Item>
) {

    @PersistenceConstructor
    constructor(
        id: Long?, name: String, publicationName: String, startDate: String, endDate: String
    ) : this(
        id,
        name,
        publicationName,
        startDate,
        endDate,
        hashSetOf()
    )
}
0 голосов
/ 06 декабря 2018

Похоже, что это ошибка, связанная со свойствами коллекции, которые устанавливаются с помощью конструктора.

Kotlin создает конструктор со всеми атрибутами, включая Set.К сожалению, это вызывает ошибку, при которой Spring Data JDBC пытается загрузить содержащийся объект из ResultSet внешнего объекта.Вместо этого он должен выполнить другой выбор, который он делает, когда свойство можно установить только через setter или "wither".

Пожалуйста, подайте проблему в https://jira.spring.io/projects/DATAJDBC

В качестве обходного пути исключите коллекцию, оцененнуюатрибуты из конструктора.Поскольку я почти ничего не знаю о Kotlin, я не могу сказать вам, как это сделать.

...