@SqlResultSetMapping列:具有子实体的实体

que*_*nto 6 java sql entity hibernate

我有测试实体:

public class Test {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "duration", nullable = false)
private int duration;
@Column(name = "test_name", nullable = false, unique = true)
private String testName;
@Column(name = "archived", nullable = false)
private boolean archived;
@OneToMany(mappedBy = "test", fetch = FetchType.EAGER)
private Set<Question> questions;
@ManyToMany(mappedBy = "tests")
private Set<User> users;
Run Code Online (Sandbox Code Playgroud)

问题实体:

public class Question {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "is_multichoice", nullable = false)
private boolean isMultichoice;
@Column(name = "is_open", nullable = false)
private boolean isOpen;
@Column(name = "picture")
private String picture;
@Column(name = "question")
private String question;
@ManyToOne
@JoinColumn(name = "test_id", nullable = false)
private Test test;
@Column(name = "archived", nullable = false)
private boolean isArchived;
@OneToMany(mappedBy = "question", fetch = FetchType.EAGER)
private Set<Answer> answers;
Run Code Online (Sandbox Code Playgroud)

测试实体具有一组问题,问题实体具有一组答案.

我编写了SQL查询来进行测试(之所以不是HQL,你可以通过链接Hibernate HQL找到它:找不到查询的实体):

@NamedNativeQuery(name = "getCurrentTestById",
            query = "SELECT t.id as tId, t.test_name, t.duration, q.id as qId, " +
                    "q.question as question, q.is_multichoice as is_multichoice, " +
                    "q.is_open as is_open, a.id as aId, a.answer_text as answer_text  FROM result r " +
                    "JOIN test t ON r.test_id = t.id " +
                    "JOIN user u ON r.user_id = u.id " +
                    "JOIN question q ON t.id = q.test_id JOIN answer a ON q.id = a.question_id " +
                    "WHERE t.id = :testId AND u.id = :userId AND r.permission = :permissionId " +
                    "AND q.archived = false AND a.archived = false")
Run Code Online (Sandbox Code Playgroud)

现在我需要使用@SqlResultSetMapping注释将它映射到我的实体Test:

@SqlResultSetMappings({
    @SqlResultSetMapping(name="toTest",
    entities = {
            @EntityResult(entityClass = com.bionic.entities.Test.class, fields = {
                    @FieldResult(name = "id", column = "tId"),
                    @FieldResult(name = "test_name", column = "test_name"),
                    @FieldResult(name = "duration", column = "duration"),
                    @FieldResult(name = "questions.question", column = "question"),
                    @FieldResult(name = "questions.id", column = "qId"),
                    @FieldResult(name = "questions.isMultichoice", column = "is_multichoice"),
                    @FieldResult(name = "questions.isOpen", column = "is_open"),
                    @FieldResult(name = "questions.answers.id", column = "aId"),
                    @FieldResult(name = "questions.answers.answer_text", column = "answer_text"),
            })
    })
})
Run Code Online (Sandbox Code Playgroud)

我得到例外:

Caused by: org.hibernate.MappingException: dotted notation reference neither a component nor a many/one to one
Run Code Online (Sandbox Code Playgroud)

小智 2

这就是为什么框架通常是坏消息的原因。您应该遵循接口隔离原则,而不是使用 hibernate。您的应用程序不应该知道或关心如何选择您需要的数据以及表名称是什么等。只需创建一个承担此责任的存储过程并调用它,而不是在您的应用程序中包含所有垃圾代码。然后,如果您想要一种简单的映射方法,只需在最后调用 For JSON 让存储过程返回 json 即可。将对象字段映射到 JSON 对象变得轻而易举。您会发现,使用框架时,您花在框架故障排除上的时间比实际编程的时间还要多。