2015-02-24 128 views
0

我有一个实体的“通知”有大约10 ManyToOne关系被标记为FetchType.Lazy如下:HQL查询添加JOINS懒惰协会

@ManyToOne(fetch = FetchType.LAZY, optional = true) 

但是构建一个HQL查询检索通知的列表后(并不包括任何这些关系)我看看生成的SQL它包括LEFT OUTER JOIN的所有这些惰性关联

为什么包含这些应该是懒惰加载休眠?

(休眠3.6 | Postgres的)

更新:包括HQL & SQL:

public List<Notification> findUserNotifications(User user, int limit, int offset){ 

    String s = "from Notification as n "; 
    s+="where (n.user = :user or n.pool = :pool or n.client = :client or n.admin is not null "; 
    s+=") and n.dateCreated > :userStartDate "; 
    s+="order by dateCreated desc"; 
    Query query = this.getEntityManager().createQuery(s); 
    query.setParameter("user", user); 
    query.setParameter("userStartDate", user.getDateCreated()); 
    query.setParameter("pool", user.getLocalPool()); 
    query.setParameter("client", user.getLocalPool().getClient()); 
    query.setFirstResult(offset); 
    query.setMaxResults(limit); 
    return query.getResultList(); 
} 

生成的SQL:

select notificati0_.notification_id as notifica1_159_, notificati0_.admin_audience as admin7_159_, notificati0_.client_audience as client8_159_, notificati0_.client_tag_audience as client9_159_, notificati0_.custom_message as custom2_159_, notificati0_.date_created as date3_159_, notificati0_.icon as icon159_, notificati0_.message_id as message5_159_, notificati0_.pool_audience as pool10_159_, notificati0_.title_id as title6_159_, notificati0_.user_audience as user11_159_, notificati0_1_.client_user_id as client1_160_, notificati0_2_.swim_mate_id as swim1_165_, notificati0_3_.user_training_plan_id as user1_169_, notificati0_4_.user_challenge_id as user1_167_, notificati0_4_.user_id as user2_167_, notificati0_5_.session_id as session1_164_, notificati0_6_.personal_best_id as personal1_163_, notificati0_7_.competition_user_session_id as competit1_162_, notificati0_8_.user_challenge_id as user1_166_, notificati0_9_.competition_user_id as competit1_161_, notificati0_10_.user_drill_id as user1_168_ from public.notifications notificati0_ left outer join public.notification_client_user_creators notificati0_1_ on notificati0_.notification_id=notificati0_1_.notification_id left outer join public.swim_mate_notifications notificati0_2_ on notificati0_.notification_id=notificati0_2_.notification_id left outer join public.user_training_plan_notifications notificati0_3_ on notificati0_.notification_id=notificati0_3_.notification_id left outer join public.ucu_notifications notificati0_4_ on notificati0_.notification_id=notificati0_4_.notification_id left outer join public.session_notifications notificati0_5_ on notificati0_.notification_id=notificati0_5_.notification_id left outer join public.pb_notifications notificati0_6_ on notificati0_.notification_id=notificati0_6_.notification_id left outer join public.competition_session_notifications notificati0_7_ on notificati0_.notification_id=notificati0_7_.notification_id left outer join public.user_challenge_notifications notificati0_8_ on notificati0_.notification_id=notificati0_8_.notification_id left outer join public.competition_user_notifications notificati0_9_ on notificati0_.notification_id=notificati0_9_.notification_id left outer join public.user_drill_notifications notificati0_10_ on notificati0_.notification_id=notificati0_10_.notification_id where (notificati0_.user_audience=? or notificati0_.pool_audience=1 or notificati0_.client_audience=1 or notificati0_.admin_audience is not null) and notificati0_.date_created>? order by notificati0_.date_created desc limit ? 

和实体本身:

@Entity 
@Table(name = "notifications", schema = "public") 
public class Notification implements java.io.Serializable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private int notificationId; 
    private User user; 
    private String titleId; 
    private String messageId; 
    private String icon; 
    private boolean customMessage; 
    private Date dateCreated; 

    //Relations 
    private SwimMate swimMate; 
    private Session session; 
    private PersonalBest personalBest; 
    private UserChallengeUser userChallengeUser; 
    private UserChallenge userChallenge; 
    private CompetitionUserSession competitionUserSession; 
    private CompetitionUser competitionUser; 
    private UserTrainingPlan userTrainingPlan; 
    private DockActiveBand dockActiveBand; 
    private UserDrill userDrill; 
    private Pool pool; 
    private Client client; 
    private ClientTag clientTag; 
    private Admin admin; 
    private ClientUser clientUserCreator; 

    public Notification() { 
    } 

    public Notification(User user, String titleId, String messageId, String icon) { 
     super(); 
     this.user = user; 
     this.titleId = titleId; 
     this.messageId = messageId; 
     this.icon = icon; 
     this.dateCreated = Calendar.getInstance().getTime(); 
    } 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name = "notification_id", unique = true, nullable = false) 
    public int getNotificationId() { 
     return this.notificationId; 
    } 

    public void setNotificationId(int notificationId) { 
     this.notificationId = notificationId; 
    } 

    @Temporal(TemporalType.TIMESTAMP) 
    @Column(name = "date_created", nullable = false, length = 29) 
    public Date getDateCreated() { 
     return this.dateCreated; 
    } 

    public void setDateCreated(Date dateCreated) { 
     this.dateCreated = dateCreated; 
    } 

    @Length(min=10,max=40) 
    @Column(name = "title_id", nullable = false) 
    public String getTitleId() { 
     return titleId; 
    } 

    public void setTitleId(String titleId) { 
     this.titleId = titleId; 
    } 

    @Column(name = "message_id", nullable = false) 
    public String getMessageId() { 
     return this.messageId; 
    } 

    public void setMessageId(String messageId) { 
     this.messageId = messageId; 
    } 

    @Column(name = "icon", nullable = false) 
    public String getIcon() { 
     return this.icon; 
    } 

    public void setIcon(String icon) { 
     this.icon = icon; 
    } 

    @Column(name = "custom_message", nullable = false) 
    public boolean isCustomMessage() { 
     return this.customMessage; 
    } 

    public void setCustomMessage(boolean customMessage) { 
     this.customMessage = customMessage; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "user_audience", nullable = true) 
    public User getUser(){ 
     return this.user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "pool_audience", nullable = true) 
    public Pool getPool() { 
     return pool; 
    } 

    public void setPool(Pool pool) { 
     this.pool = pool; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "client_tag_audience", nullable = true) 
    public ClientTag getClientTag() { 
     return clientTag; 
    } 

    public void setClientTag(ClientTag clientTag) { 
     this.clientTag = clientTag; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "client_audience", nullable = true) 
    public Client getClient() { 
     return client; 
    } 

    public void setClient(Client client) { 
     this.client = client; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "admin_audience", nullable = true) 
    public Admin getAdmin() { 
     return admin; 
    } 

    public void setAdmin(Admin admin) { 
     this.admin = admin; 
    } 

    @ManyToOne(fetch = FetchType.LAZY, optional = true) 
    @JoinTable(name = "swim_mate_notifications", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "swim_mate_id") }) 
    public SwimMate getSwimMate() { 
     return swimMate; 
    } 

    public void setSwimMate(SwimMate swimMate) { 
     this.swimMate = swimMate; 
    } 

    @ManyToOne(fetch = FetchType.EAGER, optional = true) 
    @JoinTable(name = "session_notifications", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id", nullable=true)}, 
      inverseJoinColumns = { @JoinColumn(name = "session_id", nullable=true) }) 
    public Session getSession() { 
     return session; 
    } 

    public void setSession(Session session) { 
     this.session = session; 
    } 

    @OneToOne(fetch = FetchType.LAZY, optional = true) 
    @JoinTable(name = "pb_notifications", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id", nullable=true) }, 
      inverseJoinColumns = { @JoinColumn(name = "personal_best_id", nullable=true) }) 
    public PersonalBest getPersonalBest() { 
     return personalBest; 
    } 

    public void setPersonalBest(PersonalBest personalBest) { 
     this.personalBest = personalBest; 
    } 

    @ManyToOne(fetch = FetchType.LAZY, optional = true) 
    @JoinTable(name = "ucu_notifications", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "user_challenge_id"), @JoinColumn(name = "user_id") }) 
    public UserChallengeUser getUserChallengeUser() { 
     return userChallengeUser; 
    } 

    public void setUserChallengeUser(UserChallengeUser userChallengeUser) { 
     this.userChallengeUser = userChallengeUser; 
    } 

    @ManyToOne(fetch = FetchType.LAZY, optional = true) 
    @JoinTable(name = "user_challenge_notifications", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "user_challenge_id")}) 
    public UserChallenge getUserChallenge(){ 
     return userChallenge; 
    } 

    public void setUserChallenge(UserChallenge userChallenge) { 
     this.userChallenge = userChallenge; 
    } 

    @OneToOne(fetch = FetchType.LAZY, optional = true) 
    @JoinTable(name = "competition_session_notifications", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id", nullable=true) }, 
      inverseJoinColumns = { @JoinColumn(name = "competition_user_session_id", nullable=true)}) 
    public CompetitionUserSession getCompetitionUserSession() { 
     return competitionUserSession; 
    } 

    public void setCompetitionUserSession(CompetitionUserSession competitionUserSession) { 
     this.competitionUserSession = competitionUserSession; 
    } 

    @OneToOne(fetch = FetchType.LAZY, optional = true) 
    @JoinTable(name = "competition_user_notifications", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "competition_user_id")}) 
    public CompetitionUser getCompetitionUser() { 
     return competitionUser; 
    } 

    public void setCompetitionUser(CompetitionUser competitionUser) { 
     this.competitionUser = competitionUser; 
    } 

    @ManyToOne(fetch = FetchType.LAZY, optional = true) 
    @JoinTable(name = "user_training_plan_notifications", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "user_training_plan_id") }) 
    public UserTrainingPlan getUserTrainingPlan() { 
     return userTrainingPlan; 
    } 

    public void setUserTrainingPlan(UserTrainingPlan userTrainingPlan) { 
     this.userTrainingPlan = userTrainingPlan; 
    } 

    @ManyToOne(fetch = FetchType.LAZY, optional = true) 
    @JoinTable(name = "user_drill_notifications", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "user_drill_id") }) 
    public UserDrill getUserDrill() { 
     return userDrill; 
    } 

    public void setUserDrill(UserDrill userDrill) { 
     this.userDrill = userDrill; 
    } 

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "notification", optional = true) 
    public DockActiveBand getDockActiveBand() { 
     return dockActiveBand; 
    } 

    public void setDockActiveBand(DockActiveBand dockActiveBand) { 
     this.dockActiveBand = dockActiveBand; 
    } 

    //Log Creator Info 

    @ManyToOne(fetch = FetchType.LAZY, optional = true) 
    @Fetch(FetchMode.SELECT) 
    @JoinTable(name = "notification_client_user_creators", schema = "public", 
      joinColumns = { @JoinColumn(name = "notification_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "client_user_id") }) 
    public ClientUser getClientUserCreator() { 
     return clientUserCreator; 
    } 

    public void setClientUserCreator(ClientUser clientUserCreator) { 
     this.clientUserCreator = clientUserCreator; 
    } 

} 
+0

发布代码。发布HQL查询。发布SQL查询。 – 2015-02-24 18:39:41

+0

@JBNizet - 已添加代码 – DaveB 2015-02-24 18:50:42

回答

1

您正在使用连接表来映射toOne关联,而不是连接列(这是默认设置)。由于关联是可选的,Hibernate无法知道,只要获取主表的列,如果有关联的实体。随着连接列,它可以:

  • 如果列为空,那么多对一标注字段为空
  • 如果列不为空,那么多对一标注的字段是包含在一个慵懒的代理目标实体的ID

通过连接表,Hibernate被迫从连接表中获取列,以决定该字段是否必须设置为null或者是否必须使用代理初始化。