Не работает загрузка коллекций в DTO Hibernate

209
13 октября 2018, 14:40

Есть Entity с 4-мя @OneToMany отношениями:

@Entity
@Table(name = "userInfo")
@NamedQueries({
        @NamedQuery(name = "getCommonUser", query = "select new ru.projects.prog_ja.dto.CommonUserTransfer( " +
                " u.userId, u.firstName, i.imageL, u.rating, u.lastName, u.createDate, u.birthDate, u.userQuestions, u.userPostsComments , u.userPosts, u.answers " +
                " ) " +
                " from UserInfo as u " +
                " join  u.userImage as i " +
                " where u.userId = :id"),
})
public class UserInfo {
    public static final String GET_COMMON_USER = "getCommonUser";
    private long userId;
    private String email;
    private String firstName;
    private String lastName;
    private long rating;
    private Date createDate;
    private java.sql.Date birthDate;
    private List<Questions> userQuestions;
    private List<PostsComments> userPostsComments;
    private List<PostsInfo> userPosts;
    private List<Answer> answers;
    private UserImages userImage;
    private LogInfo logInfo;
    public UserInfo(){}
    public UserInfo(String email, String firstName, String lastName, java.sql.Date birthDate){
        this.email = email;
        this.firstName = firstName;
        this.lastName = lastName;
        this.birthDate = birthDate;
    }
    @GenericGenerator(name = "generator", strategy = "foreign",
    parameters = @org.hibernate.annotations.Parameter(name = "property", value = "logInfo"))
    @Id @GeneratedValue(generator = "generator")
    @Column(name = "user_id")
    public long getUserId() {
        return userId;
    }
    @Basic
    @Column(name = "email")
    public String getEmail() {
        return email;
    }
    @Basic
    @Column(name = "firstName")
    public String getFirstName() {
        return firstName;
    }
    @Basic
    @Column(name = "lastName")
    public String getLastName() {
        return lastName;
    }
    @Basic
    @Column(name = "rating")
    public long getRating() {
        return rating;
    }
    @Basic
    @Column(name = "createDate")
    @Temporal(TemporalType.DATE)
    public Date getCreateDate() {
        return createDate;
    }
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    @OrderColumn
    @OneToMany(mappedBy = "userInfo", cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    public List<Questions> getUserQuestions() {
        return this.userQuestions;
    }
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    @OrderColumn
    @OneToMany(mappedBy = "userInfo", cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    public List<PostsComments> getUserPostsComments() {
        return this.userPostsComments;
    }
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    @OrderColumn
    @OneToMany(mappedBy = "userInfo", cascade = CascadeType.PERSIST)
    public List<PostsInfo> getUserPosts() {
        return this.userPosts;
    }
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    @OrderColumn
    @OneToMany(mappedBy = "userInfo", cascade = CascadeType.PERSIST)
    public List<Answer> getAnswers() {
        return this.answers;
    }
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "userInfo", fetch = FetchType.EAGER, optional = false)
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    public UserImages getUserImage() {
        return userImage;
    }
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    @OneToOne(fetch = FetchType.LAZY, optional = false,cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    public LogInfo getLogInfo() {
        return logInfo;
    }
    @Column(name = "birthDate", nullable = false)
    public java.sql.Date getBirthDate() {
        return birthDate;
    }

 //Лишнее убрано
    }

К нему прилагается именованный запрос, который выбирает все значения в следующий DTO:

    public class CommonUserTransfer extends SmallUserTransfer{
    protected String lastName;
    protected java.util.Date createDate;
    protected java.util.Date birthDate;
    protected List<Questions> userQuestions;
    protected List<PostsComments> userPostsComments;
    protected List<PostsInfo> userPosts;
    protected List<Answer> answers;
    public CommonUserTransfer(long id, String firstName, byte[] userImage, long rating, String lastName,
                              java.util.Date createDate,
                              java.util.Date birthDate,
                              List<Questions> userQuestions,
                              List<PostsComments> postsComments,
                              List<PostsInfo> postsInfos,
                              List<Answer> answers) {
        super(id, firstName, userImage, rating);
        this.lastName = lastName;
        this.createDate = createDate;
        this.birthDate = birthDate;
        this.userQuestions = userQuestions;
        this.userPostsComments = postsComments;
        this.userPosts = postsInfos;
        this.answers = answers;
    }
}

Дело в том, что при исполнении данного запроса Hibernate выдаёт SQL ошибку:

   ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as col_7_0_, . as col_8_0_, . as col_9_0_, . as col_10_0_ from userInfo userinfo' at line 1

Вот весь SQL, который он генерирует:

Hibernate: select userinfo0_.user_id as col_0_0_, userinfo0_.firstName as col_1_0_, userimages1_.image_l as col_2_0_, userinfo0_.rating as col_3_0_, userinfo0_.lastName as col_4_0_, userinfo0_.createDate as col_5_0_, userinfo0_.birthDate as col_6_0_, . as col_7_0_, . as col_8_0_, . as col_9_0_, . as col_10_0_ from userInfo userinfo0_ inner join userImages userimages1_ on userinfo0_.user_id=userimages1_.user_id inner join Questions userquesti2_ on userinfo0_.user_id=userquesti2_.user_id inner join postsComments userpostsc3_ on userinfo0_.user_id=userpostsc3_.user_id inner join postsInfo userposts4_ on userinfo0_.user_id=userposts4_.user_id inner join Answer answers5_ on userinfo0_.user_id=answers5_.user_id where userinfo0_.user_id=?

Т.е. в SQL все выборы коллекции замещены на . , как будто их нет, если я начинаю использовать тип Collection<> тогда мне выдаёт, что нельзя подгружать сразу несколько коллекций, поискал в гугле, написано что сразу несколько коллекций разрешено подгружать если использовать тип List<> и аннотацию @OrderColumn для данного листа

Читал документацию Hibernate, там довольно скудно рассказано об использовании DTO в select, не знаю что с этим делать, может кто-то сталкивался с подобным?

ОБНОВЛЕНИЕ 1:

Что интересно при использовании следующего запроса:

 @NamedQuery(name = "getFullUser", query = "select u from UserInfo u " +
        " join fetch u.userImage " +
        " join fetch u.userQuestions " +
        " join fetch u.userPostsComments " +
        " join fetch u.userPosts  " +
        " join fetch u.answers  " +
        " where u.userId = :id")

запрос выполняется, но мне выдаёт ошибку, что такая сущность не найдена, хотя она есть в таблице. Если убрать join fetch коллекций(последние 4), то всё работает нормально. Мб у меня с коллекциями что-то не так настроено?

Answer 1

Не надо нагромождать сложные запросы. Достаточно получить корневой объект, и не думать о зависимостях.

@NamedQuery(name = "getCommonUser", query = "select u " +
            " from UserInfo as u " +
            " where u.userId = :id"),
READ ALSO
CSRF Spring security через ajax(json)

CSRF Spring security через ajax(json)

у меня проблема с csrf и SpringSecurityКогда я посылаю форму я получаю статус 302

209
Как перевести Spring XML конфиг в Java конфиг?

Как перевести Spring XML конфиг в Java конфиг?

Есть такой бин, в xml конфиге

194
Мавен не создает property

Мавен не создает property

В файле pomxml есть такая конструкция

194
Java - что не то с кодом

Java - что не то с кодом

Объясните, пожалуйста, intellij подчёркивает последнюю строку, ругаясь на spiffoObject, в чем причина?

182