2014-05-21 3 views
0

У меня следующие классы сущностей: Пользователь и категория. Пользователь может иметь несколько категорий. Мне нужно составить запрос, чтобы выбрать пользователя с определенными адресами электронной почты и выборки, обновленное значение которых больше, чем указано мной.Hibernate, OneToMany association - select issue

К сожалению, я получаю некоторые странные (с моей точки зрения) ошибки. Вот запрос:

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; 
    } 
} 

Спасибо заранее. Любая помощь будет высоко оценена.

+0

Показать код может помочь ... –

+0

Не могли бы вы разместить класс 'User' и' Category'? – Rohan

+0

Здесь вы идете. Спасибо, интерес к моему вопросу. – user3489820

ответ

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 

Категория не может быть отфильтрована с этим запросом, так как левое соединение fetch не позволяет использовать псевдоним в предложении 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 
+0

Благодарим за отзыв. Я попробую это в своем коде. – user3489820

+0

Добро пожаловать. Проверьте оба подхода и посмотрите, какой из них лучше подходит для вашего текущего контекста проблем. Первый легче интегрировать, а второй - лучше. –