【问题标题】:Hibernate- @OnetoMany with Where clause on CollectionHibernate-@OnetoMany 与 Collection 上的 Where 子句
【发布时间】:2015-04-16 19:18:58
【问题描述】:

在我的一对多和多对一双向关系中,我想执行以下sql-

select * from user_credential c 
join user_profile p on c.login_id = p.login_id
join user_address a on p.address_id = a.address_id
where p.profile_id = 1

但是,我得到了 sql 的结果-

select * from user_credential c 
join user_profile p on c.login_id = p.login_id
join user_address a on p.address_id = a.address_id
where p.credential_id = 1

休眠实体详细信息-

    @Entity
    @Table(name = "user_credential")
    public class UserCredential implements Serializable {
        private static final long serialVersionUID = -2839071606927921689L;

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "login_id", insertable = false, updatable = false, nullable = false)
        private int login_id = 0;

        @Column(name = "password", insertable = true, updatable = true, nullable = false)
        private String password = null;

        @OneToMany(mappedBy = "login_id", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
        private Set<UserProfile> profiles = null;
//getters/setters
}

@Entity
@Table(name = "user_profile")
public class UserProfile implements Serializable {

    private static final long serialVersionUID = 5765280899633539336L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "profile_id", length = 10, insertable = false, updatable = false, nullable = false)
    private int profile_id = 0;

    @ManyToOne
    @JoinColumn(name = "login_id", insertable = true, updatable = true, nullable = false)
    private UserCredential login_id = null;

    @Column(name = "name", length = 20, insertable = true, updatable = true, nullable = false)
    private String name = null;

    @Column(name = "age", length = 3, insertable = true, updatable = true, nullable = false)
    private byte age = 0;

    @OneToMany(mappedBy = "profile_id", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Set<UserAddress> address = null;

//getters/setters
}

@Entity
@Table(name = "user_address")
public class UserAddress extends BaseTable{
    private static final long serialVersionUID = 5036341911955664992L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "address_id", length = 10, insertable = false, updatable = false, nullable = false)
    private int address_id = 0;

    @ManyToOne
    @JoinColumn(name = "profile_id", insertable = true, updatable = true, nullable = false)
    private UserProfile profile_id = null;

    @Column(name = "state", length = 20, insertable = true, updatable = true, nullable = false)
    private String state = null;

    @Column(name = "city", length = 20, insertable = true, updatable = true, nullable = false)
    private String city = null;
//getters/setters
}

HQL:

select credential from UserCredential credential
join credential.profiles profile
where  profile.profile_id = 1

我不明白,为什么 hibernate 过滤父 id 上的数据,以及我需要的 sql 将如何执行。我正在使用休眠 4.3.8

如果需要任何其他信息,请告知。

【问题讨论】:

    标签: java hibernate jpa hql hibernate-mapping


    【解决方案1】:

    我会这样写查询:

    select distinct c 
    from Profile p
    join p.login_id c
    where p.profile_id = 1
    

    删除重复项并从Child 加入Parent 可能会帮助您解决问题。

    【讨论】:

    • 这种方法很有用,除非我在最后一个子 UserAddress 上添加连接和条件。此外,在这种情况下,join p.login_id c 不是必需的,因为它肯定会与 UserProfile 进行 join 并获取唯一的结果。出于同样的原因,distinct 也不是必需的。但是,在使用上述查询时,我在 UserCredentialUserProfile 之间遇到了 ClassCastException。
    • 您收到 ClassCastException,因为查询返回了配置文件列表,而您没有更改之前的凭据列表。
    • 我没有调试那个。当您获取 distinct c 时,它实际上返回了单条 Credential 记录,而不是 Profile。但结果还是一样。如果您需要任何其他信息,请告知。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多