Я использую Spring Boot с данными Spring Data JPA и Spring Data REST.Невозможно настроить отношения @ManyToMany и @OneToOne правильно для двунаправленных данных Spring JPA и Spring REST
У меня есть класс под названием TestExection, это установка класса, чтобы иметь несколько тестовых результатов. Когда создается TestExecution, для его создания не создаются результаты.
Позже, когда выполняется TestExecution, создаются объекты TestResult.
Эти объекты TestResult имеют отношение @OneToOne к тесту TestExecution и до сохранения TestResult объект TestExecution установлен в TestResult и вызывается сохранение (TestResult).
// Create RESULT object
TestResult testResult = new TestResult(someTestExection......);
save(testResult)
Если я сделать вызов через REST, чтобы увидеть TestResults/1/testExecution Я могу видеть testExecution, связанный с TestResult. Если я делаю тот же вызов testExecutions/1/testResults, он возвращает пустой [].
2 вопросы:
1) Мне нужно установить expclicitly вновь созданный объект TestResult в TestExecutions TestResult игровой комплект?
testExecution.getTestResults().add(testResult);
save(testExecution)
Когда я пытаюсь это он вызывает прилагаемую трассировки стека.
Hibernate: update test_execution set description=?, owner=?, version=? where id=? and version=? [WARNING] java.lang.reflect.InvocationTargetException 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:497) at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:478) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.StackOverflowError at com.miw.mcb.server.model.TestExecution.hashCode(TestExecution.java:32) at com.miw.mcb.server.model.TestResult.hashCode(TestResult.java:30) at java.util.AbstractSet.hashCode(AbstractSet.java:126) at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:448) at com.miw.mcb.server.model.TestExecution.hashCode(TestExecution.java:32) at com.miw.mcb.server.model.TestResult.hashCode(TestResult.java:30) at java.util.AbstractSet.hashCode(AbstractSet.java:126) at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:448)
ИЛИ
2) Есть ли какой-нибудь способ, чтобы его установка с отношением, так что, когда TestResult устанавливает TestExecution он может быть связан и добавил в свой список?
TestExecution
@Data
@Entity
@Table(name = "test_execution")
//@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class TestExecution {
private @Id @GeneratedValue Long id;
// TODO set back to lazy
@ManyToMany(fetch = FetchType.EAGER)
//@JsonBackReference
private Set<TestResult> testResults;
// TODO set back to lazy
@ManyToMany(fetch = FetchType.EAGER)
private Set<TestSuite> testSuites;
TestResult
@Data
@Entity
@Table(name = "test_result")
//@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class TestResult {
private @Id @GeneratedValue Long id;
// TODO switch back to lazy
@OneToOne(fetch = FetchType.EAGER)
//@JsonManagedReference
private TestExecution testExecution;
// TODO switch back to lazy
@OneToOne(fetch = FetchType.EAGER)
private TestSuite testSuite;
Оба Хранилища настроены таким же
TestExecutionRepository
@Repository
@Transactional
public interface TestExecutionRepository extends PagingAndSortingRepository<TestExecution, Long> {
TestResultRepository
@Repository
@Transactional
public interface TestResultRepository extends PagingAndSortingRepository<TestResult, Long> {
AppConfig
@Configuration
@ComponentScan({ "com.miw.mcb.server.dao.repository", "com.miw.mcb.server.model" })
public class AppConfig {
}
SpringBootApp (ReactAndSpringDataRestApplication)
@SpringBootApplication
public class ReactAndSpringDataRestApplication {
public static void main(String[] args) {
SpringApplication.run(ReactAndSpringDataRestApplication.class, args);
}
}
UPDATE: Я сделал обновления для @ManyToOne и @OneToMany, но есть еще проблема, как TestResults
являются до TestExecution
Благодарим вас за объяснение ManyToOne и OneToMany. Я думал, что неверное отображение.
После этого я получил следующую трассировку стеки при работе:
testExecution.getTestResults().add(testResult);
save(testExecution)
** Обновление для result.setTestExecution (исполнение); . Execution.getResults() добавить (результат); repo.save (исполнение); без сохранения result
первого **
java.lang.StackOverflowError: null
at com.miw.mcb.server.model.TestExecution.hashCode(TestExecution.java:26)
at com.miw.mcb.server.model.TestResult.hashCode(TestResult.java:35)
at java.util.AbstractSet.hashCode(AbstractSet.java:126)
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:448)
at com.miw.mcb.server.model.TestExecution.hashCode(TestExecution.java:26)
at com.miw.mcb.server.model.TestResult.hashCode(TestResult.java:35)
at java.util.AbstractSet.hashCode(AbstractSet.java:126)
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:448)
at com.miw.mcb.server.model.TestExecution.hashCode(TestExecution.java:26)
at com.miw.mcb.server.model.TestResult.hashCode(TestResult.java:35)
at java.util.AbstractSet.hashCode(AbstractSet.java:126)...
** Чтобы исправить это, я должен был реализовать функцию hasCode() для результата теста с Ломбками **
@EqualsAndHashCode(exclude={"id", "testExecution", "device", "testCase"})
Вы должны установить владельца сторону отношений, предоставив 'mappedBy' атрибут. При сохранении вам необходимо настроить каскады в зависимости от ваших требований. – Vaelyr