1

我正在Spring Data Spring和Spring Data REST中使用Spring Boot。無法爲雙向Spring數據JPA和Spring REST正確設置@ManyToMany和@OneToOne關係

我有一個名爲TestExection的類,它是一個具有多個TestResults的類設置。創建TestExecution時,不會創建任何結果來爲其設置。

稍後當TestExecution運行時創建TestResult對象。

這些TestResult對象與TestExecution有一個@OneToOne關係,在保存TestResult之前,TestResult對象在TestResult上設置,並調用save(TestResult)。

// Create RESULT object 
    TestResult testResult = new TestResult(someTestExection......); 
    save(testResult) 

如果我讓通過REST看到testResults/1/testExecution我可以看到與TestResult中相關的testExecution的呼叫。如果我對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) 
    

OR

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); 
} 
} 

更新:我爲@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)... 

**爲了解決這個問題,我不得不實施與龍目測試結果**

@EqualsAndHashCode(exclude={"id", "testExecution", "device", "testCase"}) 
+0

您需要提供'mappedBy'屬性建立關係的業主方。堅持時,您需要根據您的要求設置級聯。 – Vaelyr

回答

2

的hasCode()函數,我認爲你正在做的錯誤的選擇JPA註釋。此外,我不明白這是如何工作的。

實際上,@ManyToMany關係表示一種關係,其中實體的每個元素都可以與另一個實體中的任何人關聯。你需要一箇中間表that。這意味着一個單獨的TestResult可能會與許多執行相關聯。

另一方面,您提供了一個@OneToOne映射,這只是另一種方式,從另一端僅爲該對象提供一個實體實例。

你管理它的樣子看起來像你想擁有的是一個@OneToMany,這將使TestExecution控制testResults集,這意味着測試執行可以有不止一個結果,但每個結果只屬於一個執行。

TestExecution:

@OneToMany(fetch=FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="testExecution") 
private Set<TestResult> testResults; 

的TestResult:

@ManyToOne(fetch=FetchType.EAGER) 
@JoinColumn(name="id_test_result") 
private TestExecution testExecution; 

這樣,你讓TextExecution管理其TestResult中收集(使用CascadeType.ALL保存TestExecution對象時將變更傳播到集合) 。

參見:

+0

感謝您對ManyToOne和OneToMany的解釋。我認爲我的映射不正確。 我仍然有一個問題,但從現在我繼續得到相同的結果。 「TestResult」如何傳播到TestExecution對象中? 我必須保存'TestResult'然後拿這個對象並將其添加到'TestExecution'集?或者應該在TestResult對象上設置'TestExecution'來保存'TestResult'? – ALM

+0

例如:用'TestExecution'設置'TestResult'仍留有空白結果在「TestExecution」 設置保存(TestResult中) 不要我再撥打電話加入到'TestExecution' testExecution.getTestResults這個(保存)。新增(TestResult中); 保存(testExecution) – ALM

+0

它看起來像我將不得不實現我自己的hashCode()也停止重複。我嘗試了一個基本的,但它不起作用,所以我會考慮在這方面的工作。 謝謝 – ALM