Java 休眠一对多标准';行不通

Java 休眠一对多标准';行不通,java,hibernate,Java,Hibernate,我拥有以下实体: @Entity @Table(name = "author") public class Author implements Serializable { private static final long serialVersionUID = 12345L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "author_id") private int authorId; @C

我拥有以下实体:

@Entity
@Table(name = "author")
public class Author implements Serializable {
private static final long serialVersionUID = 12345L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "author_id")
private int authorId;

@Column(name = "author_bio")
private String authorBio;

@Column(name = "author_email")
private String authorEmail;

@Column(name = "author_favourite_section")
private String authorFavouriteSection;

@Column(name = "author_password")
private String authorPassword;

@Column(name = "author_username")
private String authorUsername;

@OneToOne(mappedBy = "author", fetch = FetchType.LAZY)
private Blog blog;

@OneToMany(mappedBy = "author", fetch = FetchType.LAZY)
private List<Post> posts;

// getters and setters
正确的结果将与作者、筛选的帖子和标记一起返回

但是我需要用hibernate来做

因此,我想使用hibernate查找所有写过包含适当标记的文章的作者。 所有那些只有包含指定标签的帖子的作者(见上文-‘Football’、‘Basketball’)都必须被退回

我写了这段代码:

final DetachedCriteria authorCriteria = DetachedCriteria.forClass(Author.class, "author");
authorCriteria.createAlias("author.posts", "post");
authorCriteria.createAlias("post.tags", "tag");
Criterion football = Restrictions.eq("tag.tagName", "Football");
Criterion basketball = Restrictions.eq("tag.tagName", "Basketball");
authorCriteria.add(Restrictions.or(football, basketball));
authorCriteria
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
final List<Author> result = (List<Author>)getConfiguredHibernateTemplate().findByCriteria(authorCriteria);

如何使用hibernate实现预期的正确过滤结果?

您要求一位作者写一篇关于足球或篮球的博客:

DetachedCriteria.forClass(Author.class, "author");
碰巧这位作者还写了一些关于其他事情的博客。所以你得到了你想要的。在sql语句中,您要求投影,而在hibernate中,您要求ORM获取对象(author)及其posts集合。

我尝试使用投影(authorCriteria.setResultTransformer(CriteriaSpecification.projection)

final DetachedCriteria authorCriteria=DetachedCriteria.forClass(Author.class,“Author”);
authorCriteria.createAlias(“author.posts”、“post”);
authorCriteria.createAlias(“post.tags”、“tag”);
最终标准football=Restrictions.eq(“tag.tagName”、“football”);
最终标准basketball=Restrictions.eq(“tag.tagName”、“basketball”);
添加(限制或(足球、篮球));
setResultTransformer(标准规范.投影);
最终名单

好的,这是正确的,我可以分析这些数据,并将它们排序到作者->帖子列表->带有特定帖子的标签。但这在代码中是额外的工作。 我想hibernate可能有更优雅的方式来返回我需要或不需要的过滤数据。如果没有,那么我对hibernate感到失望。然后使用一些spring jdbc模板或mybatis之类的东西会更方便


使用方法“然后您可以选择Post作为您的根实体”涉及到对数据库的额外查询。为什么我们需要做这些额外的工作?如果hibernate不能运行我想要的查询并以我喜欢的方式返回结果,那么它似乎不够灵活和有用。

嗨,Frank,感谢您阅读和回答我的问题。我确实感谢您花费的时间。主要目的(问题/问题)我想解决的是——获取所有写过包含适当标签的帖子的作者。结果应该返回所有这些作者,并且只返回包含标签的帖子(足球或篮球)已传递到hibernate。我不需要作者及其所有文章。只有包含适当标记的文章才应返回用于特定作者筛选其他文章。您知道如何在hibernate中实现此目的的解决方案吗?我还尝试使用org.hibernate.annotations.FilterDef进行此操作,但看起来无法获得预期的结果。然后您可以选择作为您的根实体发布,而不是编写或创建我在下面添加的答案
@Entity
@Table(name = "tag")
public class Tag implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "tag_id")
private int tagId;

@Column(name = "tag_name")
private String tagName;

@ManyToMany(mappedBy = "tags", fetch = FetchType.LAZY)
private Set<Post> posts = new HashSet<Post>();

// getters and setters  
SELECT  a.author_id, a.author_bio, p.post_id, p.post_subject, t.tag_id, t.tag_name from author a
join blog b
on a.author_id = b.blog_author_id
join post p
on p.post_author_id = a.author_id
join post_tag pt
on p.post_id = pt.post_id
join tag t
on t.tag_id = pt.tag_id
where t.tag_name in ('Football', 'Basketball')
final DetachedCriteria authorCriteria = DetachedCriteria.forClass(Author.class, "author");
authorCriteria.createAlias("author.posts", "post");
authorCriteria.createAlias("post.tags", "tag");
Criterion football = Restrictions.eq("tag.tagName", "Football");
Criterion basketball = Restrictions.eq("tag.tagName", "Basketball");
authorCriteria.add(Restrictions.or(football, basketball));
authorCriteria
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
final List<Author> result = (List<Author>)getConfiguredHibernateTemplate().findByCriteria(authorCriteria);
select this_.author_id as author_i1_0_2_, this_.author_bio as author_b2_0_2_, this_.author_email as author_e3_0_2_, this_.author_favourite_section as author_f4_0_2_, this_.author_password as author_p5_0_2_, this_.author_username as author_u6_0_2_, post1_.post_id as post_id1_2_0_, post1_.post_author_id as post_aut4_2_0_, post1_.blog_id as blog_id5_2_0_, post1_.post_body as post_bod2_2_0_, post1_.post_subject as post_sub3_2_0_, tags5_.post_id as post_id1_2_, tag2_.tag_id as tag_id2_3_, tag2_.tag_id as tag_id1_4_1_, tag2_.tag_name as tag_name2_4_1_ from author this_ inner join post post1_ on this_.author_id=post1_.post_author_id inner join post_tag tags5_ on post1_.post_id=tags5_.post_id inner join tag tag2_ on tags5_.tag_id=tag2_.tag_id where (tag2_.tag_name=? or tag2_.tag_name=?)

select blog0_.blog_id as blog_id1_1_0_, blog0_.blog_author_id as blog_aut3_1_0_, blog0_.blog_title as blog_tit2_1_0_ from blog blog0_ where blog0_.blog_author_id=?

select posts0_.post_author_id as post_aut4_0_0_, posts0_.post_id as post_id1_2_0_, posts0_.post_id as post_id1_2_1_, posts0_.post_author_id as post_aut4_2_1_, posts0_.blog_id as blog_id5_2_1_, posts0_.post_body as post_bod2_2_1_, posts0_.post_subject as post_sub3_2_1_ from post posts0_ where posts0_.post_author_id=?
DetachedCriteria.forClass(Author.class, "author");
final DetachedCriteria authorCriteria = DetachedCriteria.forClass(Author.class, "author");
    authorCriteria.createAlias("author.posts", "post");
    authorCriteria.createAlias("post.tags", "tag");
    final Criterion football = Restrictions.eq("tag.tagName", "Football");
    final Criterion basketball = Restrictions.eq("tag.tagName", "Basketball");
    authorCriteria.add(Restrictions.or(football, basketball));
    authorCriteria.setResultTransformer(CriteriaSpecification.PROJECTION);
    final List<Author> result = (List<Author>) getConfiguredHibernateTemplate().findByCriteria(authorCriteria);