Hibernate,OneToMany关联 - 选择问题

时间:2014-05-21 11:47:07

标签: java hibernate jpa orm one-to-many

我有以下实体类: 用户和类别。用户可能有多个类别。 我需要编写一个查询来选择具有某些特定电子邮件和获取类别的用户,其更新值大于我指定的值。

不幸的是,我得到一些奇怪的(从我的观点来看)错误。 这是一个查询:

String selectQuery = "from User as user left outer join user.categories as category with category.updated >= :after where user.email = :email";
User u = (User)sessionFactory.getCurrentSession().createQuery(selectQuery).
            setString("email", email).
            setCalendar("after", after).
            setResultTransformer(RootEntityResultTransformer.INSTANCE).
            uniqueResult();
return u;

我也试过这个问题:

String selectQuery = "from User as user left outer join user.categories as category where category.updated >= :after and user.email = :email";

我收到错误消息:

java.lang.ClassCastException: Category cannot be cast to User

有人有任何线索吗?错误消息对我来说似乎很奇怪,因为我从用户中选择,而不是从类别中选择。 P.S当然,如果用户根本没有任何类别,查询应该有效。

以下是实体:

@Entity
@Table(name = "USER", uniqueConstraints = {
        @UniqueConstraint(columnNames = {"EMAIL"})
})
public class User extends AbstractTimestampEntity implements Serializable {

    public User() {

    }

    private Integer id;

    private String email;

    private Set<Category> categories = null;

    @Id
    @Column(name = "ID")
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    @NotEmpty
    @Email
    @Column(name = "EMAIL")
    public String getEmail() {
        return email;
    }

    @Cascade( { org.hibernate.annotations.CascadeType.PERSIST } )
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    public Set<Category> getCategories() {
        return categories;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setCategories(Set<Category> categories) {
        this.categories = categories;
    }
}


@Entity
@Table(name = "CATEGORY")
public class Category extends AbstractTimestampEntity implements Serializable {

    private Integer id;

    private User user;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)
    public Integer getId() {
        return id;
    }

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "USER_ID")
    public User getUser() {
        return user;
    }


   public void setId(Integer id) {
        this.id = id;
    }

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

@MappedSuperclass
public class AbstractTimestampEntity {

    private Calendar created;

    private Calendar updated;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CREATED")
    public Calendar getCreated() {
        return created;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "UPDATED")
    public Calendar getUpdated() {
        return updated;
    }

    public void setCreated(Calendar created) {
        this.created = created;
    }

    public void setUpdated(Calendar updated) {
        this.updated = updated;
    }
}

提前谢谢你。 任何帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

“FETCH”选项将始终检索用户的所有类别,您必须使用Java过滤它:

String selectQuery = 
            "from User as user " +
            "left join fetch user.categories as category " +
            "where " +
            "   user.email = :email";
User user = (User) session.createQuery(selectQuery).
        setString("email", email).
        uniqueResult();
return user;
//then filter the user.categories by the after criteria

无法使用此查询过滤类别,因为左连接提取不允许您在where子句中使用别名。

为了更有效的查询,您需要放开“FETCH”,这样您也可以过滤类别,但这次您将无法检索具有其类别“部分”视图的用户。你要么取得所有孩子,要么没有。

String selectQuery = 
            "select user, category " +
            "from User as user " +
            "left join user.categories as category with category.updated >= :after " +
            "where " +
            "   user.email = :email";
List userAndCategories = session.createQuery(selectQuery).
        setString("email", email).
        setCalendar("after", after).
        list();     
//userAndCategories contains Object[] entries where the User is the Object[0] is the user and Object[1] is the Category