LEFT_OUTER_JOIN работает как INNER_JOIN

306
29 апреля 2017, 21:38

У меня имеется четыре сущности с которых я хочу вывести все поля в DTO (AllInfoView). Проблема в том, что когда я пытаюсь получить значения всех полей, LEFT_OUTER_JOIN срабатывает как INNER_JOIN (т.е. выводятся только те строки Video, для которых есть актеры). Что интересно, если я хочу получить поля только Video и Jenre, criteria отрабатывает как LEFT_OUTER_JOIN. Мне нужно вывести в DTO все строки Video в том числе и те, для которых актеры отсутствуют). Подскажите, пожалуйста, в чем здесь может быть загвоздка?

Актер:

@Entity
@Table(name= "Actor")
public class Actor {
@Id
@Column(name= "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name= "name")
private String name;
@Column(name= "birthday")
@Temporal(value = TemporalType.DATE)
private Date birthday;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "sex_id", unique = false, updatable = true)
private ActorSex actorSex;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "video_id", unique = false, updatable = true)
private Video video;

Пол актера:

@Entity
@Table
public class ActorSex {
@Id
@Column(name= "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name= "sex")
private String sex;
@OneToMany(mappedBy = "actorSex", cascade = CascadeType.ALL, fetch =    FetchType.LAZY)
private Set<Actor> actors;

Видео, которому может соответствовать несколько актеров

@Entity
@Table
public class ActorSex {
@Id
@Column(name= "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name= "sex")
private String sex;
@OneToMany(mappedBy = "actorSex", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Actor> actors;

Жанр, к которому относится видео:

@Entity
@Table
public class ActorSex {
@Id
@Column(name= "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name= "sex")
private String sex;
@OneToMany(mappedBy = "actorSex", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Actor> actors;

DTO:

public class AllInfoView {
private Long videoId;
private String videoDescription;
private String videoGenre;
private Long actorId;
private String actorName;
private String actorSex;
private Date actorBirthday;

Criteria (выдает результат как при INNER_JOIN):

Criteria crit = session.createCriteria(Video.class, "video")
                        .createAlias("actors", "actor",  JoinType.LEFT_OUTER_JOIN)
                        .createAlias("video.genre", "genre")
                        .createAlias("actor.actorSex", "sex")
                        .setProjection(Projections.projectionList()
                                        .add(Projections.property("video.id"), "videoId")
                                        .add(Projections.property("video.description"), "videoDescription")
                                        .add(Projections.property("genre.genre"), "videoGenre")
                                        .add(Projections.property("actor.id"), "actorId")
                                        .add(Projections.property("actor.name"), "actorName")
                                          .add(Projections.property("actor.birthday"), "actorBirthday")
                                        .add(Projections.property("sex.sex"), "actorSex")
                        ).setResultTransformer(Transformers.aliasToBean(AllInfoView.class));
        entitiesList = (ArrayList<AllInfoView>) crit.list();

если закомментировать строку

 .createAlias("actor.actorSex", "sex")

получим результат как при OUTER_JOIN, но не сможем получить значения с таблицы Actor(((

Answer 1

Сам спросил, сам отвечу. Hibernate генерирует следующий запрос: Hibernate генерирует следующий запрос:

 select this_.id as y0_, this_.description as y1_, genre2_.genre as y2_, actor1_.id as y3_, actor1_.name as y4_, actor1_.birthday as y5_, sex3_.sex as y6_ from Video this_ left outer join Actor actor1_ on this_.id=actor1_.video_id inner join ActorSex sex3_ on actor1_.sex_id=sex3_.id inner join VideoGenre genre2_ on this_.genre_id=genre2_.id

а нам нужно чтоб было:

select this_.id as y0_, this_.description as y1_, genre2_.genre as y2_, actor1_.id as y3_, actor1_.name as y4_, actor1_.birthday as y5_, sex3_.sex as y6_ from Video this_ left outer join Actor actor1_ on this_.id=actor1_.video_id left outer join ActorSex sex3_ on actor1_.sex_id=sex3_.id inner join VideoGenre genre2_ on this_.genre_id=genre2_.id

добиться этого можно следующим Criteria-запросом:

  Criteria crit = session.createCriteria(Video.class, "video")
                        .createAlias("actors", "actor", JoinType.LEFT_OUTER_JOIN)
                        .createAlias("video.genre", "genre")
                        .createAlias("actor.actorSex", "sex", JoinType.LEFT_OUTER_JOIN)
                        .setProjection(Projections.projectionList()
                                        .add(Projections.property("video.id"), "videoId")
                                        .add(Projections.property("video.description"), "videoDescription")
                                        .add(Projections.property("genre.genre"), "videoGenre")
                                        .add(Projections.property("actor.id"), "actorId")
                                        .add(Projections.property("actor.name"), "actorName")
                                        .add(Projections.property("actor.birthday"), "actorBirthday")
                                        .add(Projections.property("sex.sex"), "actorSex")
                        ).setResultTransformer(Transformers.aliasToBean(AllInfoView.class));
READ ALSO
Java ООП(интерфейс) [требует правки]

Java ООП(интерфейс) [требует правки]

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

229
Ошибка NullPointerException при авторизации через twitter

Ошибка NullPointerException при авторизации через twitter

ЗдравствуйтеРеализовываю авторизацию в android приложении через twitter, большая часть кода досталась от предыдущего разработчика

298
Декодер видео андроид

Декодер видео андроид

ЗдравствуйтеВо многих программах в настройках есть:

291