У меня имеется четыре сущности с которых я хочу вывести все поля в 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(((
Сам спросил, сам отвечу. 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));
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
ЗдравствуйтеРеализовываю авторизацию в android приложении через twitter, большая часть кода досталась от предыдущего разработчика
Нужно переписать данный код с JS: