JPA inheritance @EntityGraph include optional associations of subclasses

后端 未结 4 894
广开言路
广开言路 2021-02-19 01:48

Given the following domain model, I want to load all Answers including their Values and their respective sub-children and put it in an AnswerDTO<

4条回答
  •  南笙
    南笙 (楼主)
    2021-02-19 02:17

    Edited after your comment:

    My apologize, I haven't undersood you issue in the first round, your issue occurs on startup of spring-data, not only when you try to call the findAll().

    So, you can now navigate the full example can be pull from my github: https://github.com/bdzzaid/stackoverflow-java/blob/master/jpa-hibernate/

    You can easlily reproduce and fix your issue inside this project.

    Effectivly, Spring data and hibernate are not capable to determinate the "selected" graph by default and you need to specify the way to collect the selected option.

    So first, you have to declare the NamedEntityGraphs of the class Answer

    As you can see, there is two NamedEntityGraph for the attribute value of the class Answer

    • The first for all Value without specific relationship to load

    • The second for the specific Multichoice value. If you remove this one, you reproduce the exception.

    Second, you need to be in a transactional context answerRepository.findAll() if you want to fetch data in type LAZY

    @Entity
    @Table(name = "answer")
    @NamedEntityGraphs({
        @NamedEntityGraph(
                name = "graph.Answer", 
                attributeNodes = @NamedAttributeNode(value = "value")
        ),
        @NamedEntityGraph(
                name = "graph.AnswerMultichoice",
                attributeNodes = @NamedAttributeNode(value = "value"),
                subgraphs = {
                        @NamedSubgraph(
                                name = "graph.AnswerMultichoice.selected",
                                attributeNodes = {
                                        @NamedAttributeNode("selected")
                                }
                        )
                }
        )
    }
    )
    public class Answer
    {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(updatable = false, nullable = false)
        private int id;
    
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name = "value_id", referencedColumnName = "id")
        private Value value;
    // ..
    }
    

提交回复
热议问题